Skip to content

Commit bff939d

Browse files
Harden build script with dry-run, checksums, and validation
1 parent d1f9368 commit bff939d

2 files changed

Lines changed: 116 additions & 11 deletions

File tree

pkg_build.sh

Lines changed: 105 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,48 @@
22
set -euo pipefail
33

44
CWD="$(pwd)"
5-
tmpdir="$CWD/tmp/tmp.$((RANDOM % 1000000))"
65
version_override="${FVPLUS_VERSION_OVERRIDE:-}"
76
today_version="$(date +"%Y.%m.%d")"
87
version="${today_version}.01"
98
plgfile="$CWD/folderview.plus.plg"
109
xmlfile="$CWD/folderview.plus.xml"
10+
release_guard_script="$CWD/scripts/release_guard.sh"
1111
archive_prefix="folderview.plus"
1212
icon_ext_regex='^(png|jpg|jpeg|gif|webp|svg|bmp|ico|avif)$'
13+
validate_after_build=true
14+
dry_run=false
15+
tmpdir=""
16+
17+
print_usage() {
18+
cat <<'EOF'
19+
Usage: pkg_build.sh [options]
20+
--beta [N] Build beta package version (YYYY.MM.DD-beta or -betaN)
21+
--dry-run Show computed version/output paths without writing files
22+
--validate Run scripts/release_guard.sh after build (default: enabled)
23+
--no-validate Skip post-build release guard validation
24+
-h, --help Show this help
25+
EOF
26+
}
27+
28+
require_commands() {
29+
local missing=()
30+
local cmd
31+
for cmd in "$@"; do
32+
if ! command -v "$cmd" >/dev/null 2>&1; then
33+
missing+=("$cmd")
34+
fi
35+
done
36+
if [ "${#missing[@]}" -gt 0 ]; then
37+
echo "ERROR: Missing required commands: ${missing[*]}" >&2
38+
exit 1
39+
fi
40+
}
41+
42+
cleanup_tmpdir() {
43+
if [ -n "${tmpdir:-}" ] && [ -d "${tmpdir}" ]; then
44+
rm -rf "${tmpdir}"
45+
fi
46+
}
1347

1448
is_stable_version() {
1549
[[ "${1:-}" =~ ^[0-9]{4}\.[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]
@@ -130,16 +164,50 @@ should_package_file() {
130164
}
131165

132166
# Parse flags
133-
# Usage: pkg_build.sh [--beta [N]]
167+
# Usage: pkg_build.sh [--beta [N]] [--dry-run] [--validate|--no-validate]
134168
# --beta -> YYYY.MM.DD-beta (beta branch)
135169
# --beta 2 -> YYYY.MM.DD-beta2 (beta branch)
136-
# (no flag) -> YYYY.MM.DD.UU (main branch, stable; zero-padded update suffix)
170+
# --dry-run -> Print build plan without writing files
171+
# (no --beta)-> YYYY.MM.DD.UU (main branch, stable; zero-padded update suffix)
137172
BETA=false
138173
BETA_NUM=""
139-
if [ "${1:-}" = "--beta" ]; then
140-
BETA=true
141-
if [ -n "${2:-}" ] && [ "${2:-}" -eq "${2:-}" ] 2>/dev/null; then
142-
BETA_NUM="${2:-}"
174+
while [[ $# -gt 0 ]]; do
175+
case "${1:-}" in
176+
--beta)
177+
BETA=true
178+
if [[ -n "${2:-}" && "${2:-}" =~ ^[0-9]+$ ]]; then
179+
BETA_NUM="${2:-}"
180+
shift
181+
fi
182+
;;
183+
--dry-run)
184+
dry_run=true
185+
;;
186+
--validate)
187+
validate_after_build=true
188+
;;
189+
--no-validate)
190+
validate_after_build=false
191+
;;
192+
-h|--help)
193+
print_usage
194+
exit 0
195+
;;
196+
*)
197+
echo "Unknown argument: ${1}" >&2
198+
print_usage >&2
199+
exit 1
200+
;;
201+
esac
202+
shift
203+
done
204+
205+
require_commands tar sha256sum md5sum sed find date awk grep cp chmod mkdir rm mktemp sort tail
206+
if [ "$validate_after_build" = true ]; then
207+
require_commands bash
208+
if [ ! -f "$release_guard_script" ]; then
209+
echo "ERROR: Missing release guard script: $release_guard_script" >&2
210+
exit 1
143211
fi
144212
fi
145213

@@ -189,7 +257,27 @@ while [ -f "$filename" ]; do
189257
filename="$CWD/archive/$archive_prefix-$version.txz"
190258
done
191259

192-
mkdir -p "$tmpdir"
260+
xml_date=""
261+
if [[ "$version" =~ ^([0-9]{4})\.([0-9]{2})\.([0-9]{2})(\.[0-9]+|-beta[0-9]*)?$ ]]; then
262+
xml_date="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]}"
263+
fi
264+
265+
if [ "$dry_run" = true ]; then
266+
echo "Dry run: no files will be written."
267+
echo "Version: $version"
268+
echo "Branch: $branch"
269+
echo "Archive target: $filename"
270+
echo "PLG file: $plgfile"
271+
if [ -n "$xml_date" ]; then
272+
echo "CA template date: $xml_date"
273+
fi
274+
echo "Post-build validation: $validate_after_build"
275+
exit 0
276+
fi
277+
278+
mkdir -p "$CWD/tmp"
279+
tmpdir="$(mktemp -d "$CWD/tmp/build.XXXXXX")"
280+
trap cleanup_tmpdir EXIT
193281

194282
cd "$CWD/src/folderview.plus"
195283
while IFS= read -r -d '' file; do
@@ -207,14 +295,16 @@ tar -cJf "$filename" *
207295

208296
cd "$CWD"
209297
md5=$(md5sum "$filename" | awk '{print $1}')
298+
sha256=$(sha256sum "$filename" | awk '{print $1}')
299+
sha256_file="${filename}.sha256"
300+
printf '%s %s\n' "$sha256" "$(basename "$filename")" > "$sha256_file"
210301

211302
# Update version and md5 in plg file
212303
sed -i "s/<!ENTITY version.*>/<!ENTITY version \"$version\">/" "$plgfile"
213304
sed -i "s/<!ENTITY md5.*>/<!ENTITY md5 \"$md5\">/" "$plgfile"
214305

215306
# Keep CA template date aligned with the release version date.
216-
if [[ "$version" =~ ^([0-9]{4})\.([0-9]{2})\.([0-9]{2})(\.[0-9]+|-beta[0-9]*)?$ ]]; then
217-
xml_date="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]}"
307+
if [ -n "$xml_date" ]; then
218308
if [ -f "$xmlfile" ]; then
219309
sed -i "s|<Date>.*</Date>|<Date>${xml_date}</Date>|" "$xmlfile"
220310
else
@@ -227,10 +317,14 @@ fi
227317
sed -i 's|/main/folderview.plus.plg|/'"$branch"'/folderview.plus.plg|' "$plgfile"
228318
sed -i 's|/main/archive/|/'"$branch"'/archive/|' "$plgfile"
229319

230-
rm -R "$CWD/tmp"
320+
if [ "$validate_after_build" = true ]; then
321+
bash "$release_guard_script"
322+
fi
231323

232324
echo "Package created: $filename"
233325
echo "Version: $version"
234326
echo "MD5: $md5"
327+
echo "SHA256: $sha256"
328+
echo "SHA256 file: $sha256_file"
235329
echo "Branch: $branch"
236330
echo "PLG file updated"

tests/versioning-guard.test.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ test('pkg_build blocks stable override dates that are not today', () => {
3636
assert.match(pkgBuild, /override_date="\$\(stable_date_part \"\$version_override\"\)"/);
3737
});
3838

39+
test('pkg_build includes dependency preflight, safe temp cleanup, dry-run, and checksum outputs', () => {
40+
assert.match(pkgBuild, /require_commands tar sha256sum md5sum sed find date awk grep cp chmod mkdir rm mktemp sort tail/);
41+
assert.match(pkgBuild, /tmpdir="\$\(mktemp -d \"\$CWD\/tmp\/build\.XXXXXX\"\)"/);
42+
assert.match(pkgBuild, /trap cleanup_tmpdir EXIT/);
43+
assert.match(pkgBuild, /--dry-run/);
44+
assert.match(pkgBuild, /Post-build validation: \$validate_after_build/);
45+
assert.match(pkgBuild, /sha256=\$\(sha256sum "\$filename" \| awk '\{print \$1\}'\)/);
46+
assert.match(pkgBuild, /printf '%s %s\\n' "\$sha256" "\$\(basename "\$filename"\)" > "\$sha256_file"/);
47+
assert.doesNotMatch(pkgBuild, /rm -R "\$CWD\/tmp"/);
48+
});
49+
3950
test('release_guard blocks future-dated versions', () => {
4051
assert.match(releaseGuard, /Version date \(\$\{VERSION_DATE\}\) is in the future/);
4152
assert.match(releaseGuard, /TODAY_DATE="\$\(date \+\"%Y\.%m\.%d\"\)"/);

0 commit comments

Comments
 (0)