feat: Add support for custom CLI command shortcuts #180
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build Electron App | |
on: | |
push: | |
branches: | |
- main | |
pull_request: | |
jobs: | |
build-macos: | |
runs-on: macos-latest | |
timeout-minutes: 20 | |
env: | |
APPLE_ID: ${{ secrets.APPLE_ID }} | |
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} | |
APPLE_DEVELOPER_TEAM_ID: ${{ secrets.APPLE_DEVELOPER_TEAM_ID }} | |
# DEBUG: electron-osx-sign*,electron-notarize* | |
DEBUG: electron-osx-sign:warn,electron-osx-sign:error,electron-notarize:warn,electron-notarize:error | |
steps: | |
- name: Check out repository | |
uses: actions/checkout@v3 | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: '20.10.0' | |
- name: Install Python and set up venv | |
run: | | |
brew install python@3.9 | |
python3.9 -m venv myenv | |
source myenv/bin/activate | |
python3.9 -m ensurepip | |
python3.9 -m pip install --upgrade pip | |
python3.9 -m pip install setuptools | |
working-directory: ./jccm | |
- name: Install dependencies | |
run: | | |
source myenv/bin/activate | |
npm install | |
working-directory: ./jccm | |
- name: Install appdmg | |
run: | | |
source myenv/bin/activate | |
npm install --save-dev appdmg | |
working-directory: ./jccm | |
- name: Generate Keychain Credentials | |
run: | | |
# Generate keychain name and password dynamically | |
export KEYCHAIN_NAME="build.keychain" | |
export KEYCHAIN_PASSWORD=$(openssl rand -base64 12) | |
# Mask the password to hide it from logs | |
echo "::add-mask::$KEYCHAIN_PASSWORD" | |
# Store them in the GITHUB_ENV to use in later steps | |
echo "KEYCHAIN_NAME=$KEYCHAIN_NAME" >> $GITHUB_ENV | |
echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> $GITHUB_ENV | |
- name: Install signing certificate | |
run: | | |
echo "Decode signing certificate..." | |
echo "${{ secrets.SIGNING_CERTIFICATE }}" | base64 --decode > signing_certificate.p12 | |
echo "${{ secrets.INSTALLING_CERTIFICATE }}" | base64 --decode > installing_certificate.p12 | |
echo "Creating keychain..." | |
security create-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN_NAME | |
echo "Setting default keychain..." | |
security default-keychain -s $KEYCHAIN_NAME | |
echo "Unlocking keychain..." | |
security unlock-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN_NAME | |
echo "Preventing keychain from locking..." | |
security set-keychain-settings -t 3600 $KEYCHAIN_NAME | |
security show-keychain-info $KEYCHAIN_NAME | |
echo "Showing keychain info..." | |
security show-keychain-info $KEYCHAIN_NAME | |
echo "Importing certificate..." | |
security import signing_certificate.p12 -k $KEYCHAIN_NAME -P "${{ secrets.SIGNING_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign | |
security import installing_certificate.p12 -k $KEYCHAIN_NAME -P "${{ secrets.INSTALLING_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign -T /usr/bin/productbuild | |
echo "Listing keychains..." | |
security list-keychains -s $KEYCHAIN_NAME | |
echo "Setting key partition list..." | |
security set-key-partition-list -S apple-tool:,apple: -s -k $KEYCHAIN_PASSWORD $KEYCHAIN_NAME | |
working-directory: ./jccm | |
- name: Build and package (arm64) | |
run: | | |
attempts=0 | |
max_attempts=3 | |
while [ $attempts -lt $max_attempts ]; do | |
echo "Attempting build and notarization for arm64 (Attempt $((attempts + 1)))..." | |
security unlock-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN_NAME | |
security show-keychain-info $KEYCHAIN_NAME | |
if source myenv/bin/activate && npm run make -- --platform=darwin --arch=arm64; then | |
echo "Build and notarization succeeded for arm64." | |
break | |
else | |
echo "Build and notarization failed. Retrying..." | |
attempts=$((attempts + 1)) | |
sleep 30 | |
fi | |
if [ $attempts -eq $max_attempts ]; then | |
echo "Failed after $max_attempts attempts." | |
exit 1 | |
fi | |
done | |
working-directory: ./jccm | |
- name: Build and package (x64) | |
run: | | |
attempts=0 | |
max_attempts=3 | |
while [ $attempts -lt $max_attempts ]; do | |
echo "Attempting build and notarization for x64 (Attempt $((attempts + 1)))..." | |
security unlock-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN_NAME | |
security show-keychain-info $KEYCHAIN_NAME | |
if source myenv/bin/activate && npm run make -- --platform=darwin --arch=x64; then | |
echo "Build and notarization succeeded for x64." | |
break | |
else | |
echo "Build and notarization failed. Retrying..." | |
attempts=$((attempts + 1)) | |
sleep 30 | |
fi | |
if [ $attempts -eq $max_attempts ]; then | |
echo "Failed after $max_attempts attempts." | |
exit 1 | |
fi | |
done | |
working-directory: ./jccm | |
- name: Notarize and Staple Packages | |
run: | | |
# set -ex # Exit on error and print commands | |
set -e # Exit on error | |
function notarize_and_verify() { | |
architecture=$1 | |
pkg_path="./out/make/jccm-darwin-$architecture.pkg" | |
attempts=0 | |
max_attempts=3 | |
while (( $attempts < $max_attempts )); do | |
echo "Attempting notarization ($((attempts + 1)) of $max_attempts) for $pkg_path..." | |
echo "Storing notary credentials..." | |
xcrun notarytool store-credentials jccm \ | |
--apple-id $APPLE_ID \ | |
--team-id $APPLE_DEVELOPER_TEAM_ID \ | |
--password $APPLE_APP_SPECIFIC_PASSWORD | |
security unlock-keychain -p $KEYCHAIN_PASSWORD $KEYCHAIN_NAME | |
security show-keychain-info $KEYCHAIN_NAME | |
if xcrun notarytool submit $pkg_path --keychain-profile jccm --wait; then | |
echo "Notarization succeeded." | |
break | |
else | |
echo "Notarization failed. Retrying..." | |
attempts=$((attempts + 1)) | |
sleep 30 # Wait before retrying | |
fi | |
if (( $attempts == $max_attempts )); then | |
echo "Failed after $max_attempts attempts." | |
exit 1 | |
fi | |
done | |
echo "Stapling the Notarization Ticket to $pkg_path..." | |
xcrun stapler staple $pkg_path | |
echo "Verifying the Notarization of $pkg_path..." | |
spctl -a -t install -vv $pkg_path | |
} | |
notarize_and_verify "arm64" | |
notarize_and_verify "x64" | |
set +x # Stop printing commands | |
working-directory: ./jccm | |
- name: Upload macOS artifacts | |
uses: actions/upload-artifact@v3 | |
with: | |
name: macos-installers | |
path: | | |
./jccm/out/make/*.dmg | |
./jccm/out/make/*.pkg | |
./jccm/out/make/zip/darwin/**/*.zip | |
build-windows: | |
runs-on: windows-latest | |
timeout-minutes: 20 | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: '20.10.0' | |
- name: Install dependencies | |
run: npm install | |
working-directory: ./jccm | |
- name: Build and package (x64) | |
run: | | |
npm run make -- --platform=win32 --arch=x64 | |
dir out\make\squirrel.windows\x64\ | |
working-directory: ./jccm | |
- name: Get version and filenames from package.json and .exe and .nupkg files | |
shell: pwsh | |
run: | | |
$version = (Get-Content jccm/package.json | ConvertFrom-Json).version | |
echo "version=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 | |
$basePath = "jccm/out/make/squirrel.windows/x64" | |
if (Test-Path $basePath) { | |
$exeFile = Get-ChildItem $basePath -Filter *.exe | Select-Object -First 1 | |
if ($exeFile) { | |
echo "exe_file=$($exeFile.Name)" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 | |
} else { | |
Write-Error "No .exe file found." | |
} | |
$nupkgFile = Get-ChildItem $basePath -Filter *.nupkg | Select-Object -First 1 | |
if ($nupkgFile) { | |
echo "nupkg_file=$($nupkgFile.Name)" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 | |
} else { | |
Write-Error "No .nupkg file found." | |
} | |
} else { | |
Write-Error "Directory not found: $basePath" | |
exit 1 | |
} | |
- name: Sign setup.exe with CodeSignTool | |
uses: sslcom/esigner-codesign@develop | |
with: | |
command: sign | |
username: ${{ secrets.ES_USERNAME }} | |
password: ${{ secrets.ES_PASSWORD }} | |
credential_id: ${{ secrets.ES_CREDENTIAL_ID }} | |
totp_secret: ${{ secrets.ES_TOTP_SECRET }} | |
file_path: jccm/out/make/squirrel.windows/x64/${{ env.exe_file }} | |
malware_block: false | |
override: true | |
- name: Sign Artifact (.nupkg) with CodeSignTool | |
uses: sslcom/esigner-codesign@develop | |
with: | |
command: sign | |
username: ${{ secrets.ES_USERNAME }} | |
password: ${{ secrets.ES_PASSWORD }} | |
credential_id: ${{ secrets.ES_CREDENTIAL_ID }} | |
totp_secret: ${{ secrets.ES_TOTP_SECRET }} | |
file_path: jccm/out/make/squirrel.windows/x64/${{ env.nupkg_file }} | |
malware_block: false | |
override: true | |
- name: Recreate RELEASES File | |
shell: pwsh | |
run: | | |
$version = $env:version | |
$nupkgFile = "${{ env.nupkg_file }}" | |
$basePath = "jccm/out/make/squirrel.windows/x64" | |
$nupkgPath = Join-Path $basePath $nupkgFile | |
$releasesPath = Join-Path $basePath "RELEASES" | |
if (Test-Path $nupkgPath) { | |
$hash = (Get-FileHash -Path $nupkgPath -Algorithm SHA1).Hash | |
$size = (Get-Item $nupkgPath).Length | |
"$hash $nupkgFile $size" | Out-File -FilePath $releasesPath -Encoding UTF8 | |
# Display the contents of the RELEASES file | |
Get-Content $releasesPath | ForEach-Object { Write-Host $_ } | |
} else { | |
Write-Error "Nupkg file not found: $nupkgPath" | |
exit 1 | |
} | |
- name: Upload windows artifacts | |
uses: actions/upload-artifact@v3 | |
with: | |
name: windows-installers | |
path: ./jccm/out/make/squirrel.windows/x64/* | |
build-deb: | |
runs-on: ubuntu-latest | |
timeout-minutes: 20 | |
env: | |
DEBUG: electron-installer* | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Install deb tools | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y dpkg fakeroot | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: '20.10.0' | |
- name: Install dependencies | |
working-directory: ./jccm | |
run: npm install | |
- name: Package Electron app (.deb) | |
working-directory: ./jccm | |
run: | | |
npm run make-deb | |
mv out/make/deb/x64/*.deb out/make/deb/x64/jccm-linux-x64.deb | |
ls -alR out/make | |
- name: Archive .deb artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: deb-package | |
path: ./jccm/out/make/deb/x64/*.deb | |
build-rpm: | |
runs-on: ubuntu-latest | |
timeout-minutes: 20 | |
env: | |
DEBUG: electron-installer* | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Install rpm tools | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y rpm fakeroot alien | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: '20.10.0' | |
- name: Install dependencies | |
working-directory: ./jccm | |
run: npm install | |
- name: Package Electron app (.rpm) | |
working-directory: ./jccm | |
run: | | |
npm run make-deb | |
sudo alien -v -r --scripts out/make/deb/x64/*.deb | |
mkdir -p out/make/rpm/x64 | |
mv *.rpm out/make/rpm/x64/jccm-linux-x64.rpm | |
ls -alR out/make | |
- name: Archive .rpm artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: rpm-package | |
path: ./jccm/out/make/rpm/x64/*.rpm | |
release: | |
needs: [build-macos, build-windows, build-deb, build-rpm] | |
runs-on: ubuntu-latest | |
timeout-minutes: 20 | |
steps: | |
- name: Check out repository | |
uses: actions/checkout@v3 | |
- name: Read version from package.json | |
run: echo "VERSION=$(jq -r '.version' ./jccm/package.json)" >> $GITHUB_ENV | |
- name: Download Artifacts | |
uses: actions/download-artifact@v3 | |
with: | |
path: ./installers | |
- name: Install GitHub CLI | |
run: sudo apt-get install gh | |
- name: Check for existing release and delete if it exists | |
run: | | |
if gh release view ${{ env.VERSION }}; then | |
gh release delete ${{ env.VERSION }} --yes | |
fi | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Create Release | |
id: create_release | |
uses: actions/create-release@v1.1.4 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: ${{ env.VERSION }} | |
release_name: 'Release ${{ env.VERSION }}' | |
draft: false | |
prerelease: false | |
- name: Upload Release Assets | |
run: | | |
find ./installers -type f -exec echo "Uploading {}..." \; -exec gh release upload ${{ env.VERSION }} "{}" --clobber \; | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |