Skip to content

feat: Add support for custom CLI command shortcuts #180

feat: Add support for custom CLI command shortcuts

feat: Add support for custom CLI command shortcuts #180

Workflow file for this run

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 }}