Skip to content

Build Nightly

Build Nightly #184

# Copyright (C) 2021-2024 Saturneric <eric@bktus.com>
#
# This file is part of GpgFrontend.
#
# GpgFrontend is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GpgFrontend is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
#
# The initial version of the source code is inherited from
# the gpg4usb project, which is under GPL-3.0-or-later.
#
# All the source code of GpgFrontend was modified and released by
# Saturneric <eric@bktus.com> starting on May 12, 2021.
#
# SPDX-License-Identifier: GPL-3.0-or-later
name: Build Nightly
on:
schedule:
- cron: "0 2 * * *"
workflow_dispatch:
env:
BUILD_TYPE: Release
GNUPG_VERSION: "2.4.8"
jobs:
check-changes:
runs-on: ubuntu-latest
outputs:
should_build: ${{ steps.check.outputs.should_build }}
steps:
- uses: actions/checkout@v4
with:
ref: "develop"
fetch-depth: 2
- name: Check for changes in last 24 hours
id: check
run: |
LAST_COMMIT=$(git log -1 --format=%ct)
CURRENT_TIME=$(date +%s)
TIME_DIFF=$((CURRENT_TIME - LAST_COMMIT))
if [ $TIME_DIFF -lt 86400 ]; then
echo "should_build=true" >> $GITHUB_OUTPUT
echo "Changes found in the last 24 hours"
else
echo "should_build=false" >> $GITHUB_OUTPUT
echo "No changes in the last 24 hours"
fi
build:
needs: check-changes
if: needs.check-changes.outputs.should_build == 'true'
strategy:
matrix:
os:
[
"ubuntu-22.04",
"ubuntu-24.04-arm",
"macos-13",
"macos-14",
"macos-15",
"windows-2022",
]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
- name: Set git to use LF(Windows) or CRLF(MacOS) line endings
run: |
git config --global core.autocrlf false
git config --global core.eol lf
if: runner.os == 'Windows' || runner.os == 'macOS'
- uses: actions/checkout@v4
with:
ref: "develop"
lfs: "false"
submodules: recursive
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.os }}
- name: Get Short SHA of Commit
id: vars
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Install Dependence (Linux)
run: |
sudo apt-get update
sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo
sudo apt-get -y install gcc g++ ninja-build
sudo apt-get -y install libarchive-dev libssl-dev
sudo apt-get -y install gpgsm libxcb-xinerama0 libxcb-icccm4-dev libcups2-dev libdrm-dev libegl1-mesa-dev
sudo apt-get -y install libfuse2 libgcrypt20-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev
sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libxcb-image0 gyp
sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libxcb-* libxkbcommon-x11-0
sudo apt-get -y install libwayland-cursor0 libwayland-egl1
if: runner.os == 'Linux'
- name: Codesign Configuration (macOS)
run: |
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/${{secrets.GPGFRONTEND_XCODE_PROVISIONING_PROFILE_UUID}}.provisionprofile
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
echo -n "${{secrets.MACOS_CERTIFICATE}}" | base64 --decode -o $CERTIFICATE_PATH
echo -n "${{secrets.GPGFRONTEND_XCODE_PROVISIONING_PROFILE_DATA}}" | base64 --decode -o $PP_PATH
security create-keychain -p gpgfrontend build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p gpgfrontend build.keychain
security import $CERTIFICATE_PATH -k build.keychain -P ${{secrets.MAOS_CERTIFICATE_PWD}} -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k gpgfrontend build.keychain
security set-keychain-settings -lut 3600
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
if: runner.os == 'macOS'
- name: Install Qt6
uses: jurplel/install-qt-action@v4
with:
version: "6.9.3"
cache: "true"
if: runner.os == 'Linux' || runner.os == 'macOS'
- name: Install Dependence (macOS)
run: |
brew install --formula cmake automake texinfo libarchive googletest create-dmg
if: runner.os == 'macOS'
- name: Set up MinGW (Windows)
uses: msys2/setup-msys2@v2
id: msys2
with:
update: false
release: false
cache: true
install: >-
git
zip
unzip
msys2-devel
base-devel
msys2-runtime-devel
mingw-w64-x86_64-gcc
mingw-w64-x86_64-make
mingw-w64-x86_64-cmake
mingw-w64-x86_64-qt6-base
mingw-w64-x86_64-qt6-tools
mingw-w64-x86_64-ninja
mingw-w64-x86_64-libarchive
mingw-w64-x86_64-gtest
mingw-w64-x86_64-autotools
mingw-w64-x86_64-texinfo
mingw-w64-x86_64-libassuan
mingw-w64-x86_64-ccache
if: runner.os == 'Windows'
- name: Build GpgME (macOS)
run: |
cd ${{github.workspace}}/third_party/gpgme
export CC="ccache gcc"
export CXX="ccache g++"
./autogen.sh
mkdir build && cd build
../configure --enable-static \
--disable-shared \
--enable-silent-rules \
--disable-dependency-tracking \
--enable-languages=cl \
--disable-gpgconf-test \
--disable-gpg-test \
--disable-gpgsm-test \
--disable-g13-test
make -j4
sudo make install
if: runner.os == 'macOS'
- name: Build GpgME (Windows)
shell: msys2 {0}
run: |
cd $(cygpath -u "${{github.workspace}}")
cd third_party/gpgme
export CC="ccache gcc"
export CXX="ccache g++"
export CFLAGS="${CFLAGS} -Wno-int-conversion -Wno-incompatible-pointer-types"
./autogen.sh
mkdir build && cd build
../configure --enable-maintainer-mode \
--enable-static \
--disable-shared \
--enable-silent-rules \
--disable-dependency-tracking \
--enable-languages=cl \
--disable-gpgconf-test \
--disable-gpg-test \
--disable-gpgsm-test \
--disable-g13-test \
--enable-w32-glib
make -j4
make install
if: runner.os == 'Windows'
- name: Build OpenSSL (Linux)
run: |
cd ${{github.workspace}}/third_party/openssl
export CC="ccache gcc"
export CXX="ccache g++"
./config
make -j$(nproc)
sudo make install_sw
export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH
which openssl
ldd $(which openssl) | grep ssl
openssl version -a
openssl list -kdf-algorithms || true
if: runner.os == 'Linux'
- name: Build googletest (Linux)
run: |
git clone --depth 1 --branch v1.15.2 https://github.com/google/googletest.git ${{github.workspace}}/third_party/googletest
cd ${{github.workspace}}/third_party/googletest
mkdir build && cd build
cmake -G Ninja -DBUILD_SHARED_LIBS=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
..
ninja
sudo ninja install
if: runner.os == 'Linux'
- name: Build GpgFrontend (macOS)
run: |
MACOS_MAJOR=$(sw_vers -productVersion | cut -d. -f1)
MACOS_MINOR=$(sw_vers -productVersion | cut -d. -f2)
if [[ "$MACOS_MAJOR" == "13" ]]; then
DEPLOY_TARGET="13.0"
elif [[ "$MACOS_MAJOR" == "14" ]]; then
DEPLOY_TARGET="14.0"
elif [[ "$MACOS_MAJOR" == "15" ]]; then
DEPLOY_TARGET="15.0"
else
DEPLOY_TARGET="${MACOS_MAJOR}.${MACOS_MINOR}"
fi
echo "Set MacOS Deployment Target: $DEPLOY_TARGET"
cmake -B ${{github.workspace}}/build -G Xcode \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOY_TARGET} \
-DGPGFRONTEND_XCODE_CODE_SIGN_IDENTITY="${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" \
-DGPGFRONTEND_XCODE_TEAM_ID="${{secrets.GPGFRONTEND_XCODE_TEAM_ID}}" \
-DGPGFRONTEND_XCODE_APPID="${{secrets.GPGFRONTEND_XOCDE_APPID}}" \
-DGPGFRONTEND_XCODE_PROVISIONING_PROFILE_UUID="${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID}}" \
-DGPGFRONTEND_LINK_GPGME_INTO_CORE=ON
xcodebuild -list -project ${{github.workspace}}/build/GpgFrontend.xcodeproj
cd ${{github.workspace}}/build/
xcodebuild -scheme GpgFrontend -configuration "${{env.BUILD_TYPE}}"\
-archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive archive
mkdir ${{github.workspace}}/build/package
xcodebuild -exportArchive -archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive \
-exportOptionsPlist ${{github.workspace}}/build/ExportOptions.plist \
-exportPath ${{github.workspace}}/build/package/
if: runner.os == 'macOS'
- name: Deploy Qt & Code Sign (macOS)
run: |
macdeployqt ${{github.workspace}}/build/package/GpgFrontend.app -verbose=2 -appstore-compliant -always-overwrite
codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime --timestamp ${{github.workspace}}/build/package/GpgFrontend.app
if: runner.os == 'macOS'
- name: Package & Sign App Bundle (macOS)
run: |
security -v unlock-keychain -p gpgfrontend
ditto -c -k --keepParent ${{github.workspace}}/build/package/GpgFrontend.app ${{github.workspace}}/build/GpgFrontend.app.zip
hdiutil create ${{github.workspace}}/build/tmp.dmg -ov \
-volname "GpgFrontend" -fs HFS+ -srcfolder ${{github.workspace}}/build/package/
mkdir ${{github.workspace}}/build/upload-artifact
create-dmg --codesign "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" --volicon "${{github.workspace}}/resource/lfs/icns/GpgFrontend.icns" --volname GpgFrontend --app-drop-link 600 185 --window-size 800 400 ${{github.workspace}}/build/upload-artifact/GpgFrontend.dmg ${{github.workspace}}/build/package/GpgFrontend.app
mv ${{github.workspace}}/build/upload-artifact/GpgFrontend.dmg \
${{github.workspace}}/build/upload-artifact/GpgFrontend-${{matrix.os}}-${{env.sha_short}}.dmg
mv ${{github.workspace}}/build/GpgFrontend.app.zip \
${{github.workspace}}/build/GpgFrontend-${{matrix.os}}-${{env.sha_short}}.zip
if: runner.os == 'macOS'
- name: Notarize Release Build (macOS)
run: |
xcrun notarytool submit \
--apple-id ${{secrets.APPLE_DEVELOPER_ID}} \
--team-id ${{secrets.APPLE_DEVELOPER_TEAM_ID}} \
--password ${{secrets.APPLE_DEVELOPER_ID_SECRET}} \
${{github.workspace}}/build/GpgFrontend-${{matrix.os}}-${{env.sha_short}}.zip
echo "BUILD_TYPE_LOWER=$(echo ${BUILD_TYPE} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_ENV}
echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
if: runner.os == 'macOS'
- name: Build GpgFrontend (Linux)
run: |
export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH
cmake -B ${{github.workspace}}/build -G Ninja \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DGPGFRONTEND_BUILD_APP_IMAGE=ON \
-DGPGFRONTEND_LINK_GPGME_INTO_CORE=ON
cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
if: runner.os == 'Linux'
- name: Package App Image (Linux)
run: |
mkdir ${{github.workspace}}/build/upload-artifact
cd ${{github.workspace}}/build/upload-artifact
ARCH=$(uname -m)
if [[ "$ARCH" == "x86_64" ]]; then
wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
mv linuxdeployqt-continuous-x86_64.AppImage linuxdeployqt-continuous.AppImage
EXTRA_ARGS=""
elif [[ "$ARCH" == "aarch64" ]]; then
wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-aarch64.AppImage
mv linuxdeployqt-continuous-aarch64.AppImage linuxdeployqt-continuous.AppImage
mkdir -p ${{github.workspace}}/build/artifacts/AppDir/usr/share/doc/libc6/
touch ${{github.workspace}}/build/artifacts/AppDir/usr/share/doc/libc6/copyright
EXTRA_ARGS="-unsupported-allow-new-glibc"
fi
chmod u+x linuxdeployqt-continuous.AppImage
export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH
./linuxdeployqt-continuous.AppImage \
${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop \
$EXTRA_ARGS \
-no-translations \
-extra-plugins=iconengines,platforms \
-appimage \
-executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/lib/modules
echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
if: runner.os == 'Linux'
- name: Build GpgFrontend (Windows)
shell: msys2 {0}
run: |
cd $(cygpath -u "${{github.workspace}}")
mkdir build && cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DGPGFRONTEND_LINK_GPGME_INTO_CORE=ON \
..
cmake --build . --config ${{env.BUILD_TYPE}} -- -j 4
if: runner.os == 'Windows'
- name: Generate Env Vars (Windows)
run: |
echo "SHORT_SHA=$("${{ github.sha }}".SubString(0, 8))" >> $env:GITHUB_ENV
echo "BUILD_TYPE_LOWER=$("${{env.BUILD_TYPE}}".ToLower())" >> $env:GITHUB_ENV
if: runner.os == 'Windows'
- name: Download GnuPG Binary Release (Windows)
shell: msys2 {0}
run: |
export URL="https://ftp.bktus.com/GnuPG/${{env.GNUPG_VERSION}}"
export KEY_URL="https://ftp.bktus.com/GPG_KEYS/5CA3DA246843FD03.asc"
export FILE="gnupg.zip"
export CHECKSUM_FILE="SHA256SUMS.txt"
export SIGNATURE_FILE="gnupg.zip.sig"
export GNUPGHOME=$(mktemp -d)
cd $(cygpath -u "${{github.workspace}}")
mkdir -p build/downloads
curl -o build/downloads/$FILE $URL/$FILE
curl -o build/downloads/$CHECKSUM_FILE $URL/$CHECKSUM_FILE
curl -o build/downloads/5CA3DA246843FD03.asc $KEY_URL
curl -o build/downloads/$SIGNATURE_FILE $URL/$SIGNATURE_FILE
gpg --import build/downloads/5CA3DA246843FD03.asc
gpg --verify build/downloads/$SIGNATURE_FILE build/downloads/$FILE
if [ $? -ne 0 ]; then
echo "GnuPG signature verification failed!" >&2
exit 1
fi
CHECKSUM=$(grep "$FILE" build/downloads/$CHECKSUM_FILE | awk '{print $1}')
ACTUAL_CHECKSUM=$(sha256sum build/downloads/$FILE | awk '{print $1}')
echo "Expected Checksum: $CHECKSUM"
echo "Actual Checksum: $ACTUAL_CHECKSUM"
if [ "$CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
echo "Checksum verification failed!" >&2
exit 1
fi
mkdir -p build/artifacts
unzip build/downloads/$FILE -d build/artifacts/
ls -l build/artifacts/
if: runner.os == 'Windows'
- name: Package (Windows)
shell: msys2 {0}
run: |
cd $(cygpath -u "${{github.workspace}}")
cp PrivacyPolicy.md build/artifacts/
cp README.md build/artifacts/
cp SECURITY.md build/artifacts/
cp TRANSLATORS build/artifacts/
cp COPYING build/artifacts/
cp gpgfrontend.ico build/artifacts/bin/
rm -rf build/artifacts/bin/*.a
rm -rf build/artifacts/bin/modules/*.a
mv build/artifacts/bin/modules build/artifacts/modules
touch build/artifacts/bin/ENV.ini
echo "PortableMode=true" >> build/artifacts/bin/ENV.ini
cd build
windeployqt-qt6 --no-translations --force ./artifacts/bin/libgf_core.dll
windeployqt-qt6 --no-translations --force ./artifacts/bin/libgf_ui.dll
windeployqt-qt6 --no-translations --force ./artifacts/bin/libgf_test.dll
windeployqt-qt6 --no-translations --force ./artifacts/bin/GpgFrontend.exe
for module in ./artifacts/modules/*.dll; do
windeployqt-qt6 --no-translations --force "$module"
done
mkdir upload-artifact
cd artifacts
zip -r ../upload-artifact/GpgFrontend-${{env.SHORT_SHA}}-${{matrix.os}}-x86_64.zip *
if: runner.os == 'Windows'
- name: Upload Artifact (Linux)
uses: actions/upload-artifact@master
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
path: ${{github.workspace}}/build/upload-artifact/Gpg_Frontend*.AppImage*
if: runner.os == 'Linux'
- name: Upload Artifact (macOS)
uses: actions/upload-artifact@master
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
path: ${{github.workspace}}/build/upload-artifact/*
if: runner.os == 'macOS'
- name: Upload Artifact (Windows)
uses: actions/upload-artifact@master
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
path: ${{github.workspace}}/build/upload-artifact/*
if: runner.os == 'Windows'
release:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: "develop"
lfs: "false"
submodules: recursive
- name: Re-create nightly tag
env:
GH_TOKEN: ${{ github.token }}
run: |
cd ${{github.workspace}}
gh release delete nightly --repo saturneric/GpgFrontend --cleanup-tag --yes || true
git tag -f nightly develop
git push origin nightly --force
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
path: artifacts/
pattern: gpgfrontend-*
merge-multiple: true
- name: Generate SHA256 checksums
run: |
sha256sum artifacts/* > artifacts/SHA256SUMS.txt
cat artifacts/SHA256SUMS.txt
- name: List files
run: ls -rl artifacts/
- name: Generate Nightly Release Title
id: release_title
run: echo "title=Nightly Build $(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Update Nightly Release
uses: softprops/action-gh-release@v2
with:
tag_name: nightly
name: ${{ steps.release_title.outputs.title }}
draft: false
prerelease: true
body_path: ${{ github.workspace }}/.github/NIGHTLY_RELEASE.md
files: |
artifacts/*