Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 8: [PATCH 08/17] chore(roots): integrate v31 identity and maintenance tooling

ci/release/sign-manifest.sh

Before: /dev/null · After: ci/release/sign-manifest.sh

File metadata
new file mode 100755
index 0000000000000000000000000000000000000000..5eb34cbb49805e1ade68a3469d24d902e2f79347

Download original patch · Release notes

Diff rows 1–69 of 69. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

ci/release/sign-manifest.sh ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+ # Copyright (c) 2026-present The Bitcoin Roots developers
3
+ # Distributed under the MIT software license, see the accompanying
4
+ # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
+
6
+ export LC_ALL=C
7
+ set -Eeuo pipefail
8
+
9
+ if [[ "$#" -ne 3 ]]; then
10
+ printf 'Usage: %s MANIFEST PUBLIC_KEY_FILE EXPECTED_FINGERPRINT\n' "$0" >&2
11
+ exit 2
12
+ fi
13
+
14
+ manifest=$1
15
+ public_key_file=$2
16
+ expected_fingerprint=$3
17
+ signature="${manifest}.asc"
18
+
19
+ if [[ ! -f "$manifest" ]]; then
20
+ printf 'Manifest does not exist: %s\n' "$manifest" >&2
21
+ exit 1
22
+ fi
23
+ if [[ -z "${BITCOIN_ROOTS_GPG_SK:-}" ]]; then
24
+ if [[ "${REQUIRE_RELEASE_SIGNATURE:-0}" == 1 ]]; then
25
+ printf 'Required release signing key is not configured\n' >&2
26
+ exit 1
27
+ fi
28
+ printf 'BITCOIN_ROOTS_GPG_SK is not configured; publishing an unsigned manifest\n' >&2
29
+ exit 0
30
+ fi
31
+ if [[ ! -f "$public_key_file" ]]; then
32
+ printf 'Public key does not exist: %s\n' "$public_key_file" >&2
33
+ exit 1
34
+ fi
35
+ if [[ ! "$expected_fingerprint" =~ ^[0-9A-F]{40}$ ]]; then
36
+ printf 'Expected fingerprint must be 40 uppercase hexadecimal characters\n' >&2
37
+ exit 1
38
+ fi
39
+
40
+ gpg_home="$(mktemp -d)"
41
+ cleanup() {
42
+ rm -rf -- "$gpg_home"
43
+ }
44
+ trap cleanup EXIT
45
+ chmod 0700 "$gpg_home"
46
+ export GNUPGHOME="$gpg_home"
47
+
48
+ public_fingerprint="$({
49
+ gpg --batch --with-colons --import-options show-only --import "$public_key_file" |
50
+ awk -F: '$1 == "fpr" { print $10; exit }'
51
+ })"
52
+ if [[ "$public_fingerprint" != "$expected_fingerprint" ]]; then
53
+ printf 'Unexpected release public-key fingerprint: %s\n' "$public_fingerprint" >&2
54
+ exit 1
55
+ fi
56
+
57
+ printf '%s\n' "$BITCOIN_ROOTS_GPG_SK" | gpg --batch --import >/dev/null
58
+ secret_fingerprint="$({
59
+ gpg --batch --with-colons --list-secret-keys "$expected_fingerprint" |
60
+ awk -F: '$1 == "fpr" { print $10; exit }'
61
+ })"
62
+ if [[ "$secret_fingerprint" != "$expected_fingerprint" ]]; then
63
+ printf 'The configured secret key does not match the release public key\n' >&2
64
+ exit 1
65
+ fi
66
+
67
+ gpg --batch --yes --armor --local-user "$expected_fingerprint" \
68
+ --output "$signature" --detach-sign "$manifest"
69
+ gpg --batch --verify "$signature" "$manifest"