|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Extension upload script |
| 4 | + |
| 5 | +# Usage: ./extension-upload.sh <name> <extension_version> <duckdb_version> <architecture> <s3_bucket> <copy_to_latest> <copy_to_versioned> |
| 6 | +# <name> : Name of the extension |
| 7 | +# <extension_version> : Version (commit / version tag) of the extension |
| 8 | +# <duckdb_version> : Version (commit / version tag) of DuckDB |
| 9 | +# <architecture> : Architecture target of the extension binary |
| 10 | +# <s3_bucket> : S3 bucket to upload to |
| 11 | +# <copy_to_latest> : Set this as the latest version ("true" / "false", default: "false") |
| 12 | +# <copy_to_versioned> : Set this as a versioned version that will prevent its deletion |
| 13 | + |
| 14 | +set -e |
| 15 | + |
| 16 | +if [[ $4 == wasm* ]]; then |
| 17 | + ext="/tmp/extension/$1.duckdb_extension.wasm" |
| 18 | +else |
| 19 | + ext="/tmp/extension/$1.duckdb_extension" |
| 20 | +fi |
| 21 | + |
| 22 | +echo $ext |
| 23 | + |
| 24 | +script_dir="$(dirname "$(readlink -f "$0")")" |
| 25 | + |
| 26 | +# calculate SHA256 hash of extension binary |
| 27 | +cat $ext > $ext.append |
| 28 | + |
| 29 | +if [[ $4 == wasm* ]]; then |
| 30 | + # 0 for custom section |
| 31 | + # 113 in hex = 275 in decimal, total lenght of what follows (1 + 16 + 2 + 256) |
| 32 | + # [1(continuation) + 0010011(payload) = \x93, 0(continuation) + 10(payload) = \x02] |
| 33 | + echo -n -e '\x00' >> $ext.append |
| 34 | + echo -n -e '\x93\x02' >> $ext.append |
| 35 | + # 10 in hex = 16 in decimal, lenght of name, 1 byte |
| 36 | + echo -n -e '\x10' >> $ext.append |
| 37 | + echo -n -e 'duckdb_signature' >> $ext.append |
| 38 | + # the name of the WebAssembly custom section, 16 bytes |
| 39 | + # 100 in hex, 256 in decimal |
| 40 | + # [1(continuation) + 0000000(payload) = ff, 0(continuation) + 10(payload)], |
| 41 | + # for a grand total of 2 bytes |
| 42 | + echo -n -e '\x80\x02' >> $ext.append |
| 43 | +fi |
| 44 | + |
| 45 | +# (Optionally) Sign binary |
| 46 | +if [ "$DUCKDB_EXTENSION_SIGNING_PK" != "" ]; then |
| 47 | + echo "$DUCKDB_EXTENSION_SIGNING_PK" > private.pem |
| 48 | + $script_dir/../duckdb/scripts/compute-extension-hash.sh $ext.append > $ext.hash |
| 49 | + openssl pkeyutl -sign -in $ext.hash -inkey private.pem -pkeyopt digest:sha256 -out $ext.sign |
| 50 | + rm -f private.pem |
| 51 | +fi |
| 52 | + |
| 53 | +# Signature is always there, potentially defaulting to 256 zeros |
| 54 | +truncate -s 256 $ext.sign |
| 55 | + |
| 56 | +# append signature to extension binary |
| 57 | +cat $ext.sign >> $ext.append |
| 58 | + |
| 59 | +# compress extension binary |
| 60 | +if [[ $4 == wasm_* ]]; then |
| 61 | + brotli < $ext.append > "$ext.compressed" |
| 62 | +else |
| 63 | + gzip < $ext.append > "$ext.compressed" |
| 64 | +fi |
| 65 | + |
| 66 | +set -e |
| 67 | + |
| 68 | +# Abort if AWS key is not set |
| 69 | +if [ -z "$AWS_ACCESS_KEY_ID" ]; then |
| 70 | + echo "No AWS key found, skipping.." |
| 71 | + exit 0 |
| 72 | +fi |
| 73 | + |
| 74 | +# upload versioned version |
| 75 | +if [[ $7 = 'true' ]]; then |
| 76 | + if [[ $4 == wasm* ]]; then |
| 77 | + aws s3 cp $ext.compressed s3://$5/$1/$2/$3/$4/$1.duckdb_extension.wasm --acl public-read --content-encoding br --content-type="application/wasm" |
| 78 | + else |
| 79 | + aws s3 cp $ext.compressed s3://$5/$1/$2/$3/$4/$1.duckdb_extension.gz --acl public-read |
| 80 | + fi |
| 81 | +fi |
| 82 | + |
| 83 | +# upload to latest version |
| 84 | +if [[ $6 = 'true' ]]; then |
| 85 | + if [[ $4 == wasm* ]]; then |
| 86 | + aws s3 cp $ext.compressed s3://$5/$3/$4/$1.duckdb_extension.wasm --acl public-read --content-encoding br --content-type="application/wasm" |
| 87 | + else |
| 88 | + aws s3 cp $ext.compressed s3://$5/$3/$4/$1.duckdb_extension.gz --acl public-read |
| 89 | + fi |
| 90 | +fi |
0 commit comments