Skip to content
Draft
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
5 changes: 5 additions & 0 deletions checkout-ssh/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ inputs:
git-submodules:
description: "Checkout the project with git submodules"
required: false
fetch-depth:
description: "Number of commits to fetch. 0 fetches the full history, which tools like sentry-cli need to see the commits of a release."
required: false
default: '1'
runs:
using: "composite"
steps:
- uses: actions/checkout@v3
with:
lfs: ${{ inputs.git-lfs }}
submodules: ${{ inputs.git-submodules }}
fetch-depth: ${{ inputs.fetch-depth }}
ssh-key: ${{ inputs.git-submodules != 'false' && inputs.ssh-private-key || '' }}
- uses: webfactory/ssh-agent@v0.6.0
with:
Expand Down
89 changes: 89 additions & 0 deletions delete-debug-symbols/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: 'Delete debug symbols'
description: 'Delete the debug symbols a build stored in QB Spaces, once Sentry has them'
inputs:
access-key:
description: 'Digital Ocean Access Key'
required: true
secret-key:
description: 'Digital Ocean Secret Key'
required: true
space-name:
description: 'Name of the DO Space the symbols were stored in'
required: false
default: 'quickbird-artifacts'
space-region:
description: 'Region of the DO Space'
required: false
default: 'fra1'
build-number:
description: 'Build number the symbols were stored for. Must be the same one the build jobs passed to store-debug-symbols. Falls back to the workflow run id.'
required: false
default: ''
platforms:
description: 'Space separated platform labels to delete. Platforms without stored symbols are skipped.'
required: false
default: 'ios android-apk android-aab'
runs:
using: "composite"
steps:
- name: Delete debug symbols from QB Spaces
shell: bash
env:
SPACES_ACCESS_KEY: ${{ inputs.access-key }}
SPACES_SECRET_KEY: ${{ inputs.secret-key }}
run: |
build_number="${{ inputs.build-number }}"
build_number="${build_number:-$GITHUB_RUN_ID}"

if [[ ! "$build_number" =~ ^[A-Za-z0-9._-]+$ ]]; then
echo "::error::Invalid build number '$build_number' (allowed: letters, digits, '.', '_', '-')"
exit 1
fi

if ! curl --help all 2>/dev/null | grep -q -- '--aws-sigv4'; then
echo "::error::curl on this runner cannot sign S3 requests (needs curl 7.75+), found: $(curl --version | head -1)"
exit 1
fi

# Passing the keys as --user would expose them in the process list, which
# matters on shared self-hosted runners. A 0600 config file does not.
credentials="$RUNNER_TEMP/qb-spaces-curl.conf"
(umask 077 && printf 'user = "%s:%s"\n' "$SPACES_ACCESS_KEY" "$SPACES_SECRET_KEY" > "$credentials")
trap 'rm -f "$credentials"' EXIT

endpoint="https://${{ inputs.space-name }}.${{ inputs.space-region }}.digitaloceanspaces.com"
prefix="${GITHUB_REPOSITORY##*/}/debug-symbols/$build_number"
deleted=0
requested=0

echo "Deleting debug symbols under '$prefix/'"

for platform in ${{ inputs.platforms }}; do
requested=$((requested + 1))
archive="debug-symbols-$platform.tar.gz"

curl_status=0
status="$(curl --silent --show-error --config "$credentials" \
--request DELETE \
--aws-sigv4 "aws:amz:${{ inputs.space-region }}:s3" \
--output /dev/null --write-out '%{http_code}' \
"$endpoint/$prefix/$archive")" || curl_status=$?

if [[ "$curl_status" -ne 0 ]]; then
echo "::warning::Could not reach $endpoint to delete '$archive' (curl exit $curl_status)"
continue
fi

# S3 deletes are idempotent, so a missing key answers 204 just like a hit.
case "$status" in
200|204|404)
deleted=$((deleted + 1))
echo "Deleted $archive"
;;
*)
echo "::warning::Deleting '$archive' answered HTTP $status - it will stay in the Space"
;;
esac
done

echo "Deleted $deleted of $requested key(s)"
167 changes: 167 additions & 0 deletions restore-debug-symbols/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: 'Restore debug symbols'
description: 'Download the debug symbols that store-debug-symbols put into QB Spaces for a build and extract them for the Sentry upload'
inputs:
access-key:
description: 'Digital Ocean Access Key'
required: true
secret-key:
description: 'Digital Ocean Secret Key'
required: true
space-name:
description: 'Name of the DO Space the symbols were stored in'
required: false
default: 'quickbird-artifacts'
space-region:
description: 'Region of the DO Space'
required: false
default: 'fra1'
build-number:
description: 'Build number the symbols were stored for. Must be the same one the build jobs passed to store-debug-symbols. Falls back to the workflow run id.'
required: false
default: ''
platforms:
description: 'Space separated platform labels to look for. Platforms without stored symbols are skipped.'
required: false
default: 'ios android-apk android-aab'
destination:
description: 'Directory to extract the symbols into'
required: false
default: 'debug-symbols'
fail-if-empty:
description: 'Fail if no symbols were found for the build'
required: false
default: 'true'
outputs:
symbols-dir:
description: 'Directory the symbols were extracted into (one folder per platform)'
value: ${{ steps.extract.outputs.symbols-dir }}
release:
description: 'The Sentry release name that was stored with the symbols (empty if none)'
value: ${{ steps.extract.outputs.release }}
runs:
using: "composite"
steps:
- name: Download debug symbols from QB Spaces
shell: bash
env:
SPACES_ACCESS_KEY: ${{ inputs.access-key }}
SPACES_SECRET_KEY: ${{ inputs.secret-key }}
run: |
build_number="${{ inputs.build-number }}"
build_number="${build_number:-$GITHUB_RUN_ID}"

if [[ ! "$build_number" =~ ^[A-Za-z0-9._-]+$ ]]; then
echo "::error::Invalid build number '$build_number' (allowed: letters, digits, '.', '_', '-')"
exit 1
fi

# curl signs the S3 requests itself since 7.75. Fail with a clear message
# instead of a confusing 403 when the runner ships something older.
if ! curl --help all 2>/dev/null | grep -q -- '--aws-sigv4'; then
echo "::error::curl on this runner cannot sign S3 requests (needs curl 7.75+), found: $(curl --version | head -1)"
exit 1
fi

# Passing the keys as --user would expose them in the process list, which
# matters on shared self-hosted runners. A 0600 config file does not.
credentials="$RUNNER_TEMP/qb-spaces-curl.conf"
(umask 077 && printf 'user = "%s:%s"\n' "$SPACES_ACCESS_KEY" "$SPACES_SECRET_KEY" > "$credentials")
trap 'rm -f "$credentials"' EXIT

download_dir="$RUNNER_TEMP/qb-debug-symbols-download"
rm -rf "$download_dir"
mkdir -p "$download_dir"

endpoint="https://${{ inputs.space-name }}.${{ inputs.space-region }}.digitaloceanspaces.com"
prefix="${GITHUB_REPOSITORY##*/}/debug-symbols/$build_number"
downloaded=0

echo "Looking for debug symbols under '$prefix/'"

for platform in ${{ inputs.platforms }}; do
archive="debug-symbols-$platform.tar.gz"
target="$download_dir/$archive"

curl_status=0
status="$(curl --silent --show-error --config "$credentials" \
--aws-sigv4 "aws:amz:${{ inputs.space-region }}:s3" \
--output "$target" --write-out '%{http_code}' \
"$endpoint/$prefix/$archive")" || curl_status=$?

if [[ "$curl_status" -ne 0 ]]; then
echo "::error::Downloading '$archive' failed, could not reach $endpoint (curl exit $curl_status)"
exit 1
fi

case "$status" in
200)
downloaded=$((downloaded + 1))
echo "Downloaded $archive"
;;
404)
rm -f "$target"
echo "No symbols stored for '$platform'"
;;
*)
echo "::error::Downloading '$archive' failed with HTTP $status"
cat "$target" || true
exit 1
;;
esac
done

echo "Downloaded $downloaded archive(s)"
- name: Extract debug symbols
id: extract
shell: bash
run: |
# The destination is wiped before extracting, so refuse an empty value.
if [[ -z "${{ inputs.destination }}" ]]; then
echo "::error::destination must not be empty"
exit 1
fi

download_dir="$RUNNER_TEMP/qb-debug-symbols-download"
symbols_dir="${{ inputs.destination }}"

rm -rf "$symbols_dir"
mkdir -p "$symbols_dir"

platforms=""
release=""

for archive in "$download_dir"/debug-symbols-*.tar.gz; do
[[ -f "$archive" ]] || continue

name="$(basename "$archive" .tar.gz)"
platform="${name#debug-symbols-}"
target="$symbols_dir/$platform"

mkdir -p "$target"
tar -xzf "$archive" -C "$target"
platforms="${platforms:+$platforms }$platform"
echo "Restored '$platform' from $(basename "$archive")"

if [[ -z "$release" && -f "$target/metadata.env" ]]; then
release="$(sed -n 's/^release=//p' "$target/metadata.env" | head -1)"
fi
done

if [[ -z "$platforms" ]]; then
echo "release=" >> $GITHUB_OUTPUT
echo "symbols-dir=$symbols_dir" >> $GITHUB_OUTPUT

if [[ "${{ inputs.fail-if-empty }}" == "true" ]]; then
echo "::error::No debug symbols found for this build. Either the build jobs stored none (check their 'Store debug symbols for Sentry' step), or a previous run of this job already uploaded them to Sentry and deleted them."
exit 1
fi

echo "::warning::No debug symbols found for this build - nothing to upload"
exit 0
fi

echo "release=$release" >> $GITHUB_OUTPUT
echo "symbols-dir=$symbols_dir" >> $GITHUB_OUTPUT

echo "Restored platforms: $platforms"
echo "Sentry release: ${release:-<none>}"
Loading