GPG signing logic

This commit is contained in:
Earl Warren 2023-05-26 13:03:49 +02:00
parent 358b55efd4
commit f886973249
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
6 changed files with 281 additions and 20 deletions

View file

@ -0,0 +1,10 @@
on: [ push ]
jobs:
integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Unit tests of the supporting script forgejo-release.sh
run: |
testdata/forgejo-release-test.sh test_maybe_sign_release

View file

@ -8,11 +8,15 @@ if ${VERBOSE:-false}; then set -x; fi
: ${FORGEJO:=https://codeberg.org}
: ${REPO:=forgejo-integration/forgejo}
: ${RELEASE_DIR:=dist/release}
: ${BIN_DIR:=$(mktemp -d)}
: ${TMP_DIR:=$(mktemp -d)}
: ${GNUPGHOME:=$TMP_DIR}
: ${BIN_DIR:=$TMP_DIR}
: ${TEA_VERSION:=0.9.0}
: ${RETRY:=1}
: ${DELAY:=10}
export GNUPGHOME
setup_tea() {
if ! test -f $BIN_DIR/tea ; then
curl -sL https://dl.gitea.io/tea/$TEA_VERSION/tea-$TEA_VERSION-linux-amd64 > $BIN_DIR/tea
@ -21,10 +25,10 @@ setup_tea() {
}
ensure_tag() {
if api GET repos/$REPO/tags/$TAG > /tmp/tag.json ; then
local sha=$(jq --raw-output .commit.sha < /tmp/tag.json)
if api GET repos/$REPO/tags/$TAG > $TMP_DIR/tag.json ; then
local sha=$(jq --raw-output .commit.sha < $TMP_DIR/tag.json)
if test "$sha" != "$SHA" ; then
cat /tmp/tag.json
cat $TMP_DIR/tag.json
echo "the tag SHA in the $REPO repository does not match the tag SHA that triggered the build: $SHA"
false
fi
@ -51,10 +55,31 @@ release_draft() {
api PATCH repos/$REPO/releases/$id --data-raw '{"draft": '$state'}'
}
sign_release() {
local passphrase
if test -s "$GPG_PASSPHRASE"; then
passphrase="--passphrase-file $GPG_PASSPHRASE"
fi
gpg --import --no-tty --pinentry-mode loopback $passphrase "$GPG_PRIVATE_KEY"
for asset in $RELEASE_DIR/* ; do
if [[ $asset =~ .sha256$ ]] ; then
continue
fi
gpg --armor --detach-sign --no-tty --pinentry-mode loopback $passphrase < $asset > $asset.asc
done
}
maybe_sign_release() {
if test -s "$GPG_PRIVATE_KEY"; then
sign_release
fi
}
upload() {
setup_api
setup_tea
GITEA_SERVER_TOKEN=$TOKEN $BIN_DIR/tea login add --url $FORGEJO
maybe_sign_release
upload_release
}
@ -77,8 +102,8 @@ api() {
wait_release() {
local ready=false
for i in $(seq $RETRY); do
if api GET repos/$REPO/releases/tags/$TAG | jq --raw-output .draft > /tmp/draft; then
if test "$(cat /tmp/draft)" = "false"; then
if api GET repos/$REPO/releases/tags/$TAG | jq --raw-output .draft > $TMP_DIR/draft; then
if test "$(cat $TMP_DIR/draft)" = "false"; then
ready=true
break
fi
@ -101,8 +126,8 @@ download() {
(
mkdir -p $RELEASE_DIR
cd $RELEASE_DIR
api GET repos/$REPO/releases/tags/$TAG > /tmp/assets.json
jq --raw-output '.assets[] | "\(.name) \(.browser_download_url)"' < /tmp/assets.json | while read name url ; do
api GET repos/$REPO/releases/tags/$TAG > $TMP_DIR/assets.json
jq --raw-output '.assets[] | "\(.name) \(.browser_download_url)"' < $TMP_DIR/assets.json | while read name url ; do
wget --quiet -O $name $url
done
)

View file

@ -1,12 +1,8 @@
#!/bin/sh
#!/bin/bash
# SPDX-License-Identifier: MIT
set -ex
DIR=$(mktemp -d)
trap "rm -fr $DIR" EXIT
test_teardown() {
setup_api
api DELETE repos/$REPO/releases/tags/$TAG || true
@ -20,8 +16,8 @@ test_reset_repo() {
local project="$1"
api DELETE repos/$REPO || true
api POST user/repos --data-raw '{"name":"'$project'", "auto_init":true}'
git clone $FORGEJO/$REPO $DIR/repo
SHA=$(git -C $DIR/repo rev-parse HEAD)
git clone $FORGEJO/$REPO $TMP_DIR/repo
SHA=$(git -C $TMP_DIR/repo rev-parse HEAD)
}
test_setup() {
@ -48,10 +44,10 @@ test_ensure_tag() {
# idempotent
#
ensure_tag
api GET repos/$REPO/tags/$TAG > $DIR/tag1.json
api GET repos/$REPO/tags/$TAG > $TMP_DIR/tag1.json
ensure_tag
api GET repos/$REPO/tags/$TAG > $DIR/tag2.json
diff -u $DIR/tag[12].json
api GET repos/$REPO/tags/$TAG > $TMP_DIR/tag2.json
diff -u $TMP_DIR/tag[12].json
#
# sanity check on the SHA of an existing tag
#
@ -62,12 +58,73 @@ test_ensure_tag() {
api DELETE repos/$REPO/tags/$TAG
}
test_maybe_sign_release_no_gpg() {
test_maybe_sign_release_setup no_gpg
GPG_PRIVATE_KEY=
maybe_sign_release
! test -f $RELEASE_DIR/file-one.txt.asc
}
test_maybe_sign_release_gpg_no_passphrase() {
test_maybe_sign_release_setup gpg_no_passphrase
GPG_PRIVATE_KEY=testdata/gpg-private-no-passphrase.asc
maybe_sign_release
test_maybe_sign_release_skipped
test_maybe_sign_release_verify
}
test_maybe_sign_release_gpg() {
test_maybe_sign_release_setup gpg
GPG_PRIVATE_KEY=testdata/gpg-private.asc
GPG_PASSPHRASE=testdata/gpg-private.passphrase
maybe_sign_release
test_maybe_sign_release_skipped
test_maybe_sign_release_verify
}
test_maybe_sign_release_skipped() {
! test -f $RELEASE_DIR/file-one.txt.sha256.asc
! test -f $RELEASE_DIR/file-two.txt.sha256.asc
}
test_maybe_sign_release_verify() {
for file in $RELEASE_DIR/file-one.txt $RELEASE_DIR/file-two.txt; do
gpg --verify $file.asc $file
done
}
test_maybe_sign_release_setup() {
local name="$1"
echo "========= maybe_sign_release $name ========="
RELEASE_DIR=$TMP_DIR/$name
mkdir -p $RELEASE_DIR
GNUPGHOME=$TMP_DIR/$name/.gnupg
mkdir -p $GNUPGHOME
touch $RELEASE_DIR/file-one.txt
touch $RELEASE_DIR/file-one.txt.sha256
touch $RELEASE_DIR/file-two.txt
touch $RELEASE_DIR/file-two.txt.sha256
}
test_maybe_sign_release() {
test_maybe_sign_release_no_gpg
test_maybe_sign_release_gpg_no_passphrase
test_maybe_sign_release_gpg
}
test_run() {
local user="$1"
local project="$2"
test_teardown
to_push=$DIR/binaries-releases-to-push
pulled=$DIR/binaries-releases-pulled
to_push=$TMP_DIR/binaries-releases-to-push
pulled=$TMP_DIR/binaries-releases-pulled
RELEASE_DIR=$to_push
REPO=$user/$project
test_setup $project
@ -83,6 +140,10 @@ test_run() {
test_wait_release
}
TMP_DIR=$(mktemp -d)
trap "rm -fr $TMP_DIR" EXIT
: ${TAG:=v17.8.20-1}
. $(dirname $0)/../forgejo-release.sh

81
testdata/gpg-private-no-passphrase.asc vendored Normal file
View file

@ -0,0 +1,81 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
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
=5CPG
-----END PGP PRIVATE KEY BLOCK-----

83
testdata/gpg-private.asc vendored Normal file
View file

@ -0,0 +1,83 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
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
=Ze5I
-----END PGP PRIVATE KEY BLOCK-----

1
testdata/gpg-private.passphrase vendored Normal file
View file

@ -0,0 +1 @@
admin1234