aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/make-dist.sh
blob: c1e5d07d54e4b2c35da65a831e1192f76c2ec835 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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 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 comparing 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 CHANGELOG file.
EOF
tar -xz \
	-f ${dist_base}.tar.gz \
	--to-stdout \
		${dist_base}/CHANGELOG.md \
	>>${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