diff options
-rwxr-xr-x | scripts/make-dist.sh | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/scripts/make-dist.sh b/scripts/make-dist.sh new file mode 100755 index 0000000..bb9b081 --- /dev/null +++ b/scripts/make-dist.sh @@ -0,0 +1,190 @@ +#!/bin/bash +set -euo pipefail + + +## CONSTANTS +SCRIPT_ROOT=$(realpath $(dirname ${BASH_SOURCE})) + +BUILD_DIR=dist +YOCTO_DL_URL=http://downloads.yoctoproject.org/releases/opkg + +# Channels which are only printed when verbose +LOG_VERBOSEONLY_CHANNELS=(DEBUG INFO) +log() { + local log_level=$1 + local log_msg=${@:2} + if [[ "${LOG_VERBOSEONLY_CHANNELS[@]}" == *"$log_level"* \ + && "${verbose:-}" != true ]]; then + return + else + echo "${log_level}:" $log_msg >&2 + fi +} + + +## CLI PARSING +usage() { + cat <<EOF +$(basename ${BASH_SOURCE}) [--help] [-k KEY_ID] [-m] DIST_COMMIT_HASH + +Create a source distribution archive, signature file, release notes, and +checksums. Products are stored in the `opkg:dist/` directory. + +# Options +-h,--help + Print this usage text and exit. +-k,--signing-key KEY_ID + Specify a GPG private key ID (like 0xABCEDF), which will be used to sign + the dist archive. If not specified, the default gpg signing key will be + used. +-m,--manifest + Create a plaintext manifest file of all members in the dist archive. + (Useful for comparisons with previous releases.) + +# Positional Arguments +DIST_COMMIT_HASH + The git tree-like hash from which to create the dist source archive. + +# Returns +0 on success; non-zero on failure. +EOF +} + + +dist_commit= +do_manifest= +gpg_signing_key= +opkg_root=$(realpath "${SCRIPT_ROOT}/..") +positionals=() +verbose=true + +while [ $# -ge 1 ]; do case "$1" in + -h|--help) + usage + exit 0 + ;; + -k|--signing-key) + shift + gpg_signing_key=$1 + shift + ;; + -m|--manifest) + do_manifest=true + shift + ;; + -*|--*) + log ERROR "Invalid or unknown option \"$1\"." + exit 2 + ;; + *) + positionals+=($1) + shift + ;; +esac; done + +if [ ${#positionals[@]} -lt 1 ]; then + log ERROR "Missing required positional arguments."; + usage + exit 2 +fi +dist_commit=${positionals[0]} + +log DEBUG "Using $opkg_root as the opkg project root" + + +## MAIN + +cleanup_workspace() { + log INFO 'Cleaning workspace...' + if [ -n "$workspace" ]; then + rm -r "$workspace" + fi +} + +cd "$opkg_root" + +# Create a temp workspace composed of only git-tracked files, to ensure that +# local workspace files aren't picked up in the dist. +workspace=$(mktemp -d --tmpdir opkg-dist.tmp.XXXXXX) +trap cleanup_workspace EXIT +log INFO "Using workspace $workspace" + +log INFO "Checking out commit $dist_commit ..." +git archive --format=tar $dist_commit | (cd $workspace && tar -xf -) + +# Refresh the build/ directory +test -d ./"$BUILD_DIR" && rm -r ./"$BUILD_DIR" +mkdir -p ./"$BUILD_DIR" + +log INFO 'Creating source dist archive...' +{ + cd $workspace + bash ./autogen.sh + bash ./configure + make dist + cd - +} +mv -v "$workspace"/opkg-*.tar.gz ./"$BUILD_DIR" + +# Everything else is done from within the dist/ directory +cd ./"$BUILD_DIR" +dist_base=$(ls ./opkg-*.tar.gz | sed 's/.*\(opkg-.*\)\.tar\.gz/\1/') +if [ "$do_manifest" = true ]; then + log INFO "Creating dist archive manifest file..." + tar -z -f ${dist_base}.tar.gz --list | sort >${dist_base}.manifest +fi + + +# Sign the dist archive +if [ -n "$gpg_signing_key" ]; then + log INFO "Signing with GPG key ID $gpg_signing_key ..." + arg_key="--local-user $gpg_signing_key" +else + log WARNING 'No GPG signing key specified; letting GPG choose the default.' + arg_key= +fi +gpg --armor --detach-sig \ + $arg_key \ + --output ${dist_base}.tar.gz.asc \ + --sign ${dist_base}.tar.gz +gpg \ + $arg_key \ + --verify ${dist_base}.tar.gz.asc ${dist_base}.tar.gz + +# Create the release notes file based on the changelog +log LOG 'Generating release notes...' +cat - >${dist_base}.release-notes <<EOF +Release Notes for ${dist_base} +==== + +# TODO: Cut irrelevant parts of the NEWS file. +EOF +tar -xz \ + -f ${dist_base}.tar.gz \ + --to-stdout \ + ${dist_base}/NEWS \ + >>${dist_base}.release-notes +vi ${dist_base}.release-notes + + +# Download and update the downloads.yocto.org checksum files +sum_files=( \ + ${dist_base}.tar.gz \ + ${dist_base}.tar.gz.asc \ + ${dist_base}.release-notes \ +) + +update_sums() { + # Download the sum_file from the downloads.yoctoprojects.org fileserver and + # update its values using the sum_binary. + local sum_binary=$1 + local sum_file=$2 + + wget "${YOCTO_DL_URL}/${sum_file}" + ${sum_binary} ${sum_files[@]} >>${sum_file} + ${sum_binary} --check --ignore-missing ${sum_file} +} + +update_sums md5sum MD5SUMS +update_sums sha1sum SHA1SUMS +update_sums sha256sum SHA256SUMS |