@@ -26,38 +26,42 @@ jobs:
2626
2727 steps :
2828 - name : Install dependencies
29+ shell : bash
2930 run : |
30- dnf install -y \
31- rpm-build rpm-sign rpmlint gcc make redhat-rpm-config \
32- gh gpg gpg2 gnupg2 expect rpmdevtools createrepo
31+ if command -v sudo >/dev/null 2>&1; then
32+ SUDO=sudo
33+ else
34+ SUDO=
35+ fi
36+
37+ $SUDO dnf install -y rpmdevtools gh
3338
3439 - name : Checkout repository
3540 uses : actions/checkout@v4
3641
37- - name : Import GPG key
38- run : |
39- echo "$GPG_PRIVATE_KEY" | base64 --decode | gpg --import --batch --yes
40- env :
41- GPG_PRIVATE_KEY : ${{ secrets.GPG_PRIVATE_KEY }}
42-
43- - name : Show signing subkey expiration
44- shell : bash
45- run : |
46- gpg --list-secret-keys --with-colons \
47- | awk -F: '
48- $1=="ssb" && $12 ~ /s/ {
49- keyid = $5
50- expires = $7
51- if (expires == "" || expires == "0") {
52- edate = "never"
53- } else {
54- cmd = "date -u -d @" expires " +\"%Y-%m-%d %H:%M:%S UTC\""
55- cmd | getline edate
56- close(cmd)
57- }
58- printf "signing subkey %s expires: %s\n", keyid, edate
59- }
60- '
42+ - name : Check repo key expiration
43+ uses : OpenCHAMI/gpg-signing-manager/actions/check-key-expiration@main
44+ with :
45+ key-armored-b64 : ${{ secrets.GPG_REPO_KEY_B64 }}
46+ warn-days : ' 30'
47+
48+ - name : Generate ephemeral release key
49+ id : ephemeral
50+ uses : OpenCHAMI/gpg-signing-manager/actions/gpg-ephemeral-key@main
51+ with :
52+ cert-key-armored-b64 : ${{ secrets.GPG_REPO_CERT_KEY_B64 }}
53+ name : ' ${{ github.repository }} Release'
54+ comment : ' Ephemeral key for ${{ github.ref_name }}'
55+ email : ' release@packages.openchami.org'
56+ expire : ' 1d'
57+
58+ - name : Setup RPM signing (ephemeral key)
59+ id : rpm_signing
60+ uses : OpenCHAMI/gpg-signing-manager/actions/setup-rpm-signing@main
61+ with :
62+ repo-key-armored-b64 : ${{ secrets.GPG_REPO_KEY_B64 }}
63+ ephemeral-fingerprint : ${{ steps.ephemeral.outputs.ephemeral-fingerprint }}
64+ public-key-output : public_gpg_key.asc
6165
6266 - name : Get version
6367 id : get_version
6973 else
7074 VERSION=0.0.0
7175 fi
72- echo "VERSION =${VERSION}" >> $GITHUB_ENV
76+ echo "version =${VERSION}" >> "$GITHUB_OUTPUT"
7377 echo "Version is ${VERSION}"
7478
7579 - name : Setup RPM build environment
@@ -80,114 +84,169 @@ jobs:
8084
8185 - name : Create source tarball
8286 run : |
83- mkdir -p ~/rpmbuild/SOURCES/openchami-${{ env.VERSION }}
84- cp -r ./* ~/rpmbuild/SOURCES/openchami-${{ env.VERSION }}/
85- tar -czf ~/rpmbuild/SOURCES/openchami-${{ env.VERSION }}.tar.gz \
86- -C ~/rpmbuild/SOURCES openchami-${{ env.VERSION }} \
87- --transform "s|openchami-${{ env.VERSION }}-${{ env.COMMIT_SHA }}|openchami-${{ env.VERSION }}|"
87+ mkdir -p ~/rpmbuild/SOURCES/openchami-${{ steps.get_version.outputs.version }}
88+ cp -r ./* ~/rpmbuild/SOURCES/openchami-${{ steps.get_version.outputs.version }}/
89+ tar -czf ~/rpmbuild/SOURCES/openchami-${{ steps.get_version.outputs.version }}.tar.gz \
90+ -C ~/rpmbuild/SOURCES openchami-${{ steps.get_version.outputs.version }}
8891
8992 - name : Sign source tarball
93+ env :
94+ GPG_SIGNING_FINGERPRINT : ${{ steps.ephemeral.outputs.ephemeral-fingerprint }}
9095 run : |
91- echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 --pinentry-mode loopback \
96+ set -euo pipefail
97+ unset GPG_TTY
98+ echo "Signing source tarball with key: ${GPG_SIGNING_FINGERPRINT}"
99+ gpg --batch --list-secret-keys --keyid-format LONG "${GPG_SIGNING_FINGERPRINT}"
100+ gpg --batch --yes \
101+ --no-tty --pinentry-mode loopback \
102+ --status-fd 2 \
92103 --armor --detach-sign \
93- --local-user admin@openchami.org \
94- --output ~/rpmbuild/SOURCES/openchami-${{ env.VERSION }}.tar.gz.asc \
95- ~/rpmbuild/SOURCES/openchami-${{ env.VERSION }}.tar.gz
96- env :
97- GPG_PASSPHRASE : ${{ secrets.GPG_PASSPHRASE }}
104+ --local-user "${GPG_SIGNING_FINGERPRINT}" \
105+ --output ~/rpmbuild/SOURCES/openchami-${{ steps.get_version.outputs.version }}.tar.gz.asc \
106+ ~/rpmbuild/SOURCES/openchami-${{ steps.get_version.outputs.version }}.tar.gz
98107
99108 - name : Build RPM package
100109 run : |
101110 rpmbuild -ba ~/rpmbuild/SPECS/*.spec \
102- --define "version ${{ env.VERSION }}" \
111+ --define "version ${{ steps.get_version.outputs.version }}" \
103112 --define "rel 1"
104113
105114 - name : Sign RPM packages
115+ shell : bash
116+ env :
117+ GPG_SIGNING_FINGERPRINT : ${{ steps.ephemeral.outputs.ephemeral-fingerprint }}
106118 run : |
107- for rpm in $(find ~/rpmbuild/RPMS/ -type f -name "*.rpm"); do
108- echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 --pinentry-mode loopback \
109- --detach-sign --armor "$rpm"
110- rpm --define "_gpg_name admin@openchami.org" --addsign "$rpm"
111- done
119+ set -euo pipefail
120+ unset GPG_TTY
121+ echo "Using RPM signing key: ${GPG_SIGNING_FINGERPRINT}"
122+ gpg --batch --list-secret-keys --keyid-format LONG "${GPG_SIGNING_FINGERPRINT}"
123+ sed -i '/^%__gpg_sign_cmd/d' ~/.rpmmacros
124+ echo 'Configured ~/.rpmmacros:'
125+ cat ~/.rpmmacros
126+
127+ found=0
128+ while IFS= read -r -d '' rpm_file; do
129+ found=1
130+ echo "Signing RPM: $rpm_file"
131+ rpmsign --key-id "${GPG_SIGNING_FINGERPRINT}" --addsign "$rpm_file"
132+ done < <(find ~/rpmbuild/RPMS/ -type f -name "*.rpm" -print0)
133+
134+ if [ "$found" -eq 0 ]; then
135+ echo 'No RPM packages were produced to sign' >&2
136+ exit 1
137+ fi
138+
139+ - name : Verify RPM signatures
140+ shell : bash
112141 env :
113- GPG_PASSPHRASE : ${{ secrets.GPG_PASSPHRASE }}
142+ GPG_SIGNING_FINGERPRINT : ${{ steps.ephemeral.outputs.ephemeral-fingerprint }}
143+ run : |
144+ rpm --import <(gpg --export --armor "${GPG_SIGNING_FINGERPRINT}")
145+ found=0
146+ while IFS= read -r -d '' rpm_file; do
147+ found=1
148+ output=$(rpm --checksig -v "$rpm_file" 2>&1)
149+ printf '%s\n' "$output"
150+
151+ if printf '%s\n' "$output" | grep -q 'SIGNATURES NOT OK'; then
152+ echo "RPM signature verification failed for $rpm_file" >&2
153+ exit 1
154+ fi
155+
156+ if ! printf '%s\n' "$output" | grep -Eiq 'Key ID|RSA/SHA|RSA/sha|EdDSA|pgp'; then
157+ echo "RPM appears unsigned: $rpm_file" >&2
158+ exit 1
159+ fi
160+ done < <(find ~/rpmbuild/RPMS/ -type f -name "*.rpm" -print0)
161+
162+ if [ "$found" -eq 0 ]; then
163+ echo 'No RPM packages were produced to verify' >&2
164+ exit 1
165+ fi
166+
167+ - name : Export ephemeral public key
168+ run : |
169+ printf '%s' '${{ steps.ephemeral.outputs.ephemeral-public-key }}' \
170+ | base64 -d > repo-ephemeral-public.asc
171+
172+ - name : Export repo public key
173+ run : |
174+ gpg --export --armor '${{ steps.ephemeral.outputs.repo-cert-keyid }}' > repo-public.asc
114175
115176 - name : Find RPM file
116- if : env.VERSION != '0.0.0'
177+ if : steps.get_version.outputs.version != '0.0.0'
117178 id : find_rpm
118179 run : |
119180 rpm_file=$(ls ~/rpmbuild/RPMS/noarch/*.rpm)
120181 echo "rpm_file=${rpm_file}" >> $GITHUB_ENV
121- echo "::set-output name= path:: ${rpm_file}"
182+ echo "path= ${rpm_file}" >> "$GITHUB_OUTPUT "
122183
123184 - name : Compute RPM Checksum
124- if : env.VERSION != '0.0.0'
185+ if : steps.get_version.outputs.version != '0.0.0'
125186 id : compute_checksum
126187 run : |
127188 rpm_file=$(ls ~/rpmbuild/RPMS/noarch/*.rpm)
128189 checksum=$(sha256sum "$rpm_file" | awk '{print $1}')
129190 echo "checksum=${checksum}" >> $GITHUB_ENV
130- echo "::set-output name=checksum::${checksum}"
131-
132- - name : Export Public GPG Key
133- if : env.VERSION != '0.0.0'
134- run : |
135- gpg --armor --export admin@openchami.org > public_gpg_key.asc
136-
137- - name : Get Public GPG Key Content
138- if : env.VERSION != '0.0.0'
139- id : get_pubkey
140- run : |
141- key=$(cat public_gpg_key.asc)
142- escaped_key=$(echo "$key" | sed ':a;N;$!ba;s/\n/\\n/g')
143- echo "::set-output name=pubkey::${escaped_key}"
191+ echo "checksum=${checksum}" >> "$GITHUB_OUTPUT"
144192
145193 - name : Genereate release notes
146- if : env.VERSION != '0.0.0'
194+ if : steps.get_version.outputs.version != '0.0.0'
147195 id : gen_rel_notes
148196 env :
149197 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
150198 run : |
151199 {
152- echo '# OpenCHAMI v${{ env.VERSION }}'
200+ echo '# OpenCHAMI v${{ steps.get_version.outputs.version }}'
153201 echo ''
154202 echo '**RPM SHA256 Checksum:**'
155203 echo '`${{ steps.compute_checksum.outputs.checksum }}`'
156204 echo ''
157- gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" -F tag_name='v${{ env.VERSION }}' --jq .body
205+ gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" -F tag_name='v${{ steps.get_version.outputs.version }}' --jq .body
158206 } > CHANGELOG.md
159207
160208 - name : Create GitHub Release
161- if : env.VERSION != '0.0.0'
209+ if : steps.get_version.outputs.version != '0.0.0'
162210 id : create_release
163211 uses : actions/create-release@v1
164212 env :
165213 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
166214 with :
167- tag_name : v${{ env.VERSION }}
168- release_name : v${{ env.VERSION }}
215+ tag_name : v${{ steps.get_version.outputs.version }}
216+ release_name : v${{ steps.get_version.outputs.version }}
169217 draft : false
170218 prerelease : false
171219 body_path : CHANGELOG.md
172220
173221 - name : Upload RPM to GitHub Release
174- if : env.VERSION != '0.0.0'
222+ if : steps.get_version.outputs.version != '0.0.0'
175223 uses : actions/upload-release-asset@v1
176224 env :
177225 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
178226 with :
179227 upload_url : ${{ steps.create_release.outputs.upload_url }}
180228 asset_path : ${{ steps.find_rpm.outputs.path }}
181- asset_name : openchami-${{ env.VERSION }}.rpm
229+ asset_name : openchami-${{ steps.get_version.outputs.version }}.rpm
182230 asset_content_type : application/x-rpm
183231
184- - name : Upload Public GPG Key to GitHub Release
185- if : env.VERSION != '0.0.0'
232+ - name : Upload Repo GPG Key to GitHub Release
233+ if : steps.get_version.outputs.version != '0.0.0'
234+ uses : actions/upload-release-asset@v1
235+ env :
236+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
237+ with :
238+ upload_url : ${{ steps.create_release.outputs.upload_url }}
239+ asset_path : repo-public.asc
240+ asset_name : repo_public.asc
241+ asset_content_type : text/plain
242+
243+ - name : Upload Repo Ephemeral GPG Key to GitHub Release
244+ if : steps.get_version.outputs.version != '0.0.0'
186245 uses : actions/upload-release-asset@v1
187246 env :
188247 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
189248 with :
190249 upload_url : ${{ steps.create_release.outputs.upload_url }}
191- asset_path : public_gpg_key .asc
192- asset_name : public_gpg_key .asc
250+ asset_path : repo-ephemeral-public .asc
251+ asset_name : repo_ephemeral_public .asc
193252 asset_content_type : text/plain
0 commit comments