Build and Push Electron App #25
Workflow file for this run
This file contains hidden or 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 and Push Electron App | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| build_type: | |
| description: "Platform to build for" | |
| required: true | |
| default: "all" | |
| type: choice | |
| options: | |
| - all | |
| - windows | |
| - linux | |
| - macos | |
| artifact_destination: | |
| description: "What to do with the built app" | |
| required: true | |
| default: "file" | |
| type: choice | |
| options: | |
| - none | |
| - file | |
| - release | |
| - submit | |
| jobs: | |
| build-windows: | |
| runs-on: windows-latest | |
| if: github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'windows' || github.event.inputs.build_type == '' | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: | | |
| $maxAttempts = 3 | |
| $attempt = 1 | |
| while ($attempt -le $maxAttempts) { | |
| try { | |
| npm ci | |
| break | |
| } catch { | |
| if ($attempt -eq $maxAttempts) { | |
| Write-Error "npm ci failed after $maxAttempts attempts" | |
| exit 1 | |
| } | |
| Start-Sleep -Seconds 10 | |
| $attempt++ | |
| } | |
| } | |
| - name: Get version | |
| id: package-version | |
| run: | | |
| $VERSION = (Get-Content package.json | ConvertFrom-Json).version | |
| echo "version=$VERSION" >> $env:GITHUB_OUTPUT | |
| - name: Build Windows (All Architectures) | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: npm run build && npx electron-builder --win --x64 --ia32 | |
| - name: List release files | |
| run: | | |
| dir release | |
| - name: Upload Windows x64 NSIS Installer | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_windows_x64_nsis.exe') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_windows_x64_nsis | |
| path: release/termix_windows_x64_nsis.exe | |
| retention-days: 30 | |
| - name: Upload Windows ia32 NSIS Installer | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_windows_ia32_nsis.exe') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_windows_ia32_nsis | |
| path: release/termix_windows_ia32_nsis.exe | |
| retention-days: 30 | |
| - name: Upload Windows x64 MSI Installer | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_windows_x64_msi.msi') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_windows_x64_msi | |
| path: release/termix_windows_x64_msi.msi | |
| retention-days: 30 | |
| - name: Upload Windows ia32 MSI Installer | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_windows_ia32_msi.msi') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_windows_ia32_msi | |
| path: release/termix_windows_ia32_msi.msi | |
| retention-days: 30 | |
| - name: Create Windows x64 Portable zip | |
| if: hashFiles('release/win-unpacked/*') != '' | |
| run: | | |
| Compress-Archive -Path "release\win-unpacked\*" -DestinationPath "termix_windows_x64_portable.zip" | |
| - name: Create Windows ia32 Portable zip | |
| if: hashFiles('release/win-ia32-unpacked/*') != '' | |
| run: | | |
| Compress-Archive -Path "release\win-ia32-unpacked\*" -DestinationPath "termix_windows_ia32_portable.zip" | |
| - name: Upload Windows x64 Portable | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('termix_windows_x64_portable.zip') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_windows_x64_portable | |
| path: termix_windows_x64_portable.zip | |
| retention-days: 30 | |
| - name: Upload Windows ia32 Portable | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('termix_windows_ia32_portable.zip') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_windows_ia32_portable | |
| path: termix_windows_ia32_portable.zip | |
| retention-days: 30 | |
| build-linux: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| if: github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'linux' || github.event.inputs.build_type == '' | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: | | |
| for i in 1 2 3; | |
| do | |
| if npm ci; then | |
| break | |
| else | |
| if [ $i -eq 3 ]; then | |
| exit 1 | |
| fi | |
| sleep 10 | |
| fi | |
| done | |
| npm install --force @rollup/rollup-linux-x64-gnu | |
| npm install --force @rollup/rollup-linux-arm64-gnu | |
| npm install --force @rollup/rollup-linux-arm-gnueabihf | |
| - name: Build Linux (All Architectures) | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: npm run build && npx electron-builder --linux --x64 --arm64 --armv7l | |
| - name: Rename Linux artifacts for consistency | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| cd release | |
| if [ -f "termix-${VERSION}.tar.gz" ]; then | |
| mv "termix-${VERSION}.tar.gz" "termix_linux_x64_portable.tar.gz" | |
| fi | |
| if [ -f "termix-${VERSION}-arm64.tar.gz" ]; then | |
| mv "termix-${VERSION}-arm64.tar.gz" "termix_linux_arm64_portable.tar.gz" | |
| fi | |
| if [ -f "termix-${VERSION}-armv7l.tar.gz" ]; then | |
| mv "termix-${VERSION}-armv7l.tar.gz" "termix_linux_armv7l_portable.tar.gz" | |
| fi | |
| # Rename Debian amd64 to x64 for consistency | |
| if [ -f "termix_linux_amd64_deb.deb" ]; then | |
| mv "termix_linux_amd64_deb.deb" "termix_linux_x64_deb.deb" | |
| fi | |
| cd .. | |
| - name: List release files | |
| run: | | |
| ls -la release/ | |
| - name: Upload Linux x64 AppImage | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_x64_appimage.AppImage') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_x64_appimage | |
| path: release/termix_linux_x64_appimage.AppImage | |
| retention-days: 30 | |
| - name: Upload Linux arm64 AppImage | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_arm64_appimage.AppImage') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_arm64_appimage | |
| path: release/termix_linux_arm64_appimage.AppImage | |
| retention-days: 30 | |
| - name: Upload Linux armv7l AppImage | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_armv7l_appimage.AppImage') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_armv7l_appimage | |
| path: release/termix_linux_armv7l_appimage.AppImage | |
| retention-days: 30 | |
| - name: Upload Linux x64 DEB | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_x64_deb.deb') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_x64_deb | |
| path: release/termix_linux_x64_deb.deb | |
| retention-days: 30 | |
| - name: Upload Linux arm64 DEB | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_arm64_deb.deb') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_arm64_deb | |
| path: release/termix_linux_arm64_deb.deb | |
| retention-days: 30 | |
| - name: Upload Linux armv7l DEB | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_armv7l_deb.deb') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_armv7l_deb | |
| path: release/termix_linux_armv7l_deb.deb | |
| retention-days: 30 | |
| - name: Upload Linux x64 tar.gz | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_x64_portable.tar.gz') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_x64_portable | |
| path: release/termix_linux_x64_portable.tar.gz | |
| retention-days: 30 | |
| - name: Upload Linux arm64 tar.gz | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_arm64_portable.tar.gz') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_arm64_portable | |
| path: release/termix_linux_arm64_portable.tar.gz | |
| retention-days: 30 | |
| - name: Upload Linux armv7l tar.gz | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_linux_armv7l_portable.tar.gz') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_linux_armv7l_portable | |
| path: release/termix_linux_armv7l_portable.tar.gz | |
| retention-days: 30 | |
| build-macos: | |
| runs-on: macos-latest | |
| if: github.event.inputs.build_type == 'macos' || github.event.inputs.build_type == 'all' | |
| needs: [] | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: | | |
| for i in 1 2 3; | |
| do | |
| if npm ci; then | |
| break | |
| else | |
| if [ $i -eq 3 ]; then | |
| exit 1 | |
| fi | |
| sleep 10 | |
| fi | |
| done | |
| npm install --force @rollup/rollup-darwin-arm64 | |
| npm install dmg-license | |
| - name: Check for Code Signing Certificates | |
| id: check_certs | |
| run: | | |
| if [ -n "${{ secrets.MAC_BUILD_CERTIFICATE_BASE64 }}" ] && [ -n "${{ secrets.MAC_P12_PASSWORD }}" ]; then | |
| echo "has_certs=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Import Code Signing Certificates | |
| if: steps.check_certs.outputs.has_certs == 'true' | |
| env: | |
| MAC_BUILD_CERTIFICATE_BASE64: ${{ secrets.MAC_BUILD_CERTIFICATE_BASE64 }} | |
| MAC_INSTALLER_CERTIFICATE_BASE64: ${{ secrets.MAC_INSTALLER_CERTIFICATE_BASE64 }} | |
| MAC_P12_PASSWORD: ${{ secrets.MAC_P12_PASSWORD }} | |
| MAC_KEYCHAIN_PASSWORD: ${{ secrets.MAC_KEYCHAIN_PASSWORD }} | |
| run: | | |
| APP_CERT_PATH=$RUNNER_TEMP/app_certificate.p12 | |
| INSTALLER_CERT_PATH=$RUNNER_TEMP/installer_certificate.p12 | |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | |
| echo -n "$MAC_BUILD_CERTIFICATE_BASE64" | base64 --decode -o $APP_CERT_PATH | |
| if [ -n "$MAC_INSTALLER_CERTIFICATE_BASE64" ]; then | |
| echo -n "$MAC_INSTALLER_CERTIFICATE_BASE64" | base64 --decode -o $INSTALLER_CERT_PATH | |
| fi | |
| security create-keychain -p "$MAC_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| security set-keychain-settings -lut 21600 $KEYCHAIN_PATH | |
| security unlock-keychain -p "$MAC_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| security import $APP_CERT_PATH -P "$MAC_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
| if [ -f "$INSTALLER_CERT_PATH" ]; then | |
| security import $INSTALLER_CERT_PATH -P "$MAC_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
| fi | |
| security list-keychain -d user -s $KEYCHAIN_PATH | |
| security find-identity -v -p codesigning $KEYCHAIN_PATH | |
| - name: Build macOS App Store Package | |
| if: steps.check_certs.outputs.has_certs == 'true' | |
| env: | |
| ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES: true | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| BUILD_VERSION="${{ github.run_number }}" | |
| npm run build && npx electron-builder --mac mas --universal --config.buildVersion="$BUILD_VERSION" | |
| - name: Clean up MAS keychain before DMG build | |
| if: steps.check_certs.outputs.has_certs == 'true' | |
| run: | | |
| security delete-keychain $RUNNER_TEMP/app-signing.keychain-db || true | |
| - name: Check for Developer ID Certificates | |
| id: check_dev_id_certs | |
| run: | | |
| if [ -n "${{ secrets.DEVELOPER_ID_CERTIFICATE_BASE64 }}" ] && [ -n "${{ secrets.DEVELOPER_ID_P12_PASSWORD }}" ]; then | |
| echo "has_dev_id_certs=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Import Developer ID Certificates | |
| if: steps.check_dev_id_certs.outputs.has_dev_id_certs == 'true' | |
| env: | |
| DEVELOPER_ID_CERTIFICATE_BASE64: ${{ secrets.DEVELOPER_ID_CERTIFICATE_BASE64 }} | |
| DEVELOPER_ID_INSTALLER_CERTIFICATE_BASE64: ${{ secrets.DEVELOPER_ID_INSTALLER_CERTIFICATE_BASE64 }} | |
| DEVELOPER_ID_P12_PASSWORD: ${{ secrets.DEVELOPER_ID_P12_PASSWORD }} | |
| MAC_KEYCHAIN_PASSWORD: ${{ secrets.MAC_KEYCHAIN_PASSWORD }} | |
| run: | | |
| DEV_CERT_PATH=$RUNNER_TEMP/dev_certificate.p12 | |
| DEV_INSTALLER_CERT_PATH=$RUNNER_TEMP/dev_installer_certificate.p12 | |
| KEYCHAIN_PATH=$RUNNER_TEMP/dev-signing.keychain-db | |
| echo -n "$DEVELOPER_ID_CERTIFICATE_BASE64" | base64 --decode -o $DEV_CERT_PATH | |
| if [ -n "$DEVELOPER_ID_INSTALLER_CERTIFICATE_BASE64" ]; then | |
| echo -n "$DEVELOPER_ID_INSTALLER_CERTIFICATE_BASE64" | base64 --decode -o $DEV_INSTALLER_CERT_PATH | |
| fi | |
| security create-keychain -p "$MAC_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| security set-keychain-settings -lut 21600 $KEYCHAIN_PATH | |
| security unlock-keychain -p "$MAC_KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| security import $DEV_CERT_PATH -P "$DEVELOPER_ID_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
| if [ -f "$DEV_INSTALLER_CERT_PATH" ]; then | |
| security import $DEV_INSTALLER_CERT_PATH -P "$DEVELOPER_ID_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
| fi | |
| security list-keychain -d user -s $KEYCHAIN_PATH | |
| security find-identity -v -p codesigning $KEYCHAIN_PATH | |
| - name: Build macOS DMG | |
| env: | |
| ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES: true | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} | |
| APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| run: | | |
| if [ "${{ steps.check_certs.outputs.has_certs }}" != "true" ]; then | |
| npm run build | |
| fi | |
| export GH_TOKEN="${{ secrets.GITHUB_TOKEN }}" | |
| npx electron-builder --mac dmg --universal --x64 --arm64 --publish never | |
| - name: List release directory | |
| if: steps.check_certs.outputs.has_certs == 'true' | |
| run: | | |
| ls -R release/ || echo "Release directory not found" | |
| - name: Upload macOS MAS PKG | |
| if: steps.check_certs.outputs.has_certs == 'true' && hashFiles('release/termix_macos_universal_mas.pkg') != '' && (github.event.inputs.artifact_destination == 'file' || github.event.inputs.artifact_destination == 'release' || github.event.inputs.artifact_destination == 'submit') | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: termix_macos_universal_mas | |
| path: release/termix_macos_universal_mas.pkg | |
| retention-days: 30 | |
| if-no-files-found: warn | |
| - name: Upload macOS Universal DMG | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_macos_universal_dmg.dmg') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_macos_universal_dmg | |
| path: release/termix_macos_universal_dmg.dmg | |
| retention-days: 30 | |
| - name: Upload macOS x64 DMG | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_macos_x64_dmg.dmg') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_macos_x64_dmg | |
| path: release/termix_macos_x64_dmg.dmg | |
| retention-days: 30 | |
| - name: Upload macOS arm64 DMG | |
| uses: actions/upload-artifact@v4 | |
| if: hashFiles('release/termix_macos_arm64_dmg.dmg') != '' && github.event.inputs.artifact_destination != 'none' | |
| with: | |
| name: termix_macos_arm64_dmg | |
| path: release/termix_macos_arm64_dmg.dmg | |
| retention-days: 30 | |
| - name: Check for App Store Connect API credentials | |
| if: steps.check_certs.outputs.has_certs == 'true' | |
| id: check_asc_creds | |
| run: | | |
| if [ -n "${{ secrets.APPLE_KEY_ID }}" ] && [ -n "${{ secrets.APPLE_ISSUER_ID }}" ] && [ -n "${{ secrets.APPLE_KEY_CONTENT }}" ]; then | |
| echo "has_credentials=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Setup Ruby for Fastlane | |
| if: steps.check_asc_creds.outputs.has_credentials == 'true' && github.event.inputs.artifact_destination == 'submit' | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.2" | |
| bundler-cache: false | |
| - name: Install Fastlane | |
| if: steps.check_asc_creds.outputs.has_credentials == 'true' && github.event.inputs.artifact_destination == 'submit' | |
| run: | | |
| gem install fastlane -N | |
| - name: Deploy to App Store Connect (TestFlight) | |
| if: steps.check_asc_creds.outputs.has_credentials == 'true' && github.event.inputs.artifact_destination == 'submit' | |
| run: | | |
| PKG_FILE=$(find release -name "*.pkg" -type f | head -n 1) | |
| if [ -z "$PKG_FILE" ]; then | |
| exit 1 | |
| fi | |
| mkdir -p ~/private_keys | |
| echo "${{ secrets.APPLE_KEY_CONTENT }}" | base64 --decode > ~/private_keys/AuthKey_${{ secrets.APPLE_KEY_ID }}.p8 | |
| xcrun altool --upload-app -f "$PKG_FILE" \ | |
| --type macos \ | |
| --apiKey "${{ secrets.APPLE_KEY_ID }}" \ | |
| --apiIssuer "${{ secrets.APPLE_ISSUER_ID }}" | |
| continue-on-error: true | |
| - name: Clean up keychains | |
| if: always() | |
| run: | | |
| security delete-keychain $RUNNER_TEMP/app-signing.keychain-db || true | |
| security delete-keychain $RUNNER_TEMP/dev-signing.keychain-db || true | |
| submit-to-chocolatey: | |
| runs-on: windows-latest | |
| if: github.event.inputs.artifact_destination == 'submit' | |
| needs: [build-windows] | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| $VERSION = (Get-Content package.json | ConvertFrom-Json).version | |
| echo "version=$VERSION" >> $env:GITHUB_OUTPUT | |
| - name: Download Windows x64 MSI artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: termix_windows_x64_msi | |
| path: artifact | |
| - name: Get MSI file info | |
| id: msi-info | |
| run: | | |
| $VERSION = "${{ steps.package-version.outputs.version }}" | |
| $MSI_FILE = Get-ChildItem -Path artifact -Filter "*.msi" | Select-Object -First 1 | |
| $MSI_NAME = $MSI_FILE.Name | |
| $CHECKSUM = (Get-FileHash -Path $MSI_FILE.FullName -Algorithm SHA256).Hash | |
| echo "msi_name=$MSI_NAME" >> $env:GITHUB_OUTPUT | |
| echo "checksum=$CHECKSUM" >> $env:GITHUB_OUTPUT | |
| - name: Prepare Chocolatey package | |
| run: | | |
| $VERSION = "${{ steps.package-version.outputs.version }}" | |
| $CHECKSUM = "${{ steps.msi-info.outputs.checksum }}" | |
| $MSI_NAME = "${{ steps.msi-info.outputs.msi_name }}" | |
| $DOWNLOAD_URL = "https://github.com/Termix-SSH/Termix/releases/download/release-$VERSION-tag/$MSI_NAME" | |
| New-Item -ItemType Directory -Force -Path "choco-build" | |
| Copy-Item -Path "chocolatey\*" -Destination "choco-build" -Recurse -Force | |
| $installScript = Get-Content "choco-build\tools\chocolateyinstall.ps1" -Raw -Encoding UTF8 | |
| $installScript = $installScript -replace 'DOWNLOAD_URL_PLACEHOLDER', $DOWNLOAD_URL | |
| $installScript = $installScript -replace 'CHECKSUM_PLACEHOLDER', $CHECKSUM | |
| [System.IO.File]::WriteAllText("$PWD\choco-build\tools\chocolateyinstall.ps1", $installScript, [System.Text.UTF8Encoding]::new($false)) | |
| $nuspec = Get-Content "choco-build\termix-ssh.nuspec" -Raw -Encoding UTF8 | |
| $nuspec = $nuspec -replace 'VERSION_PLACEHOLDER', $VERSION | |
| [System.IO.File]::WriteAllText("$PWD\choco-build\termix-ssh.nuspec", $nuspec, [System.Text.UTF8Encoding]::new($false)) | |
| - name: Install Chocolatey | |
| run: | | |
| Set-ExecutionPolicy Bypass -Scope Process -Force | |
| [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 | |
| iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) | |
| - name: Pack Chocolatey package | |
| run: | | |
| cd choco-build | |
| choco pack termix-ssh.nuspec | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "Chocolatey push failed with exit code $LASTEXITCODE" | |
| } | |
| - name: Check for Chocolatey API Key | |
| id: check_choco_key | |
| run: | | |
| if ("${{ secrets.CHOCOLATEY_API_KEY }}" -ne "") { | |
| echo "has_key=true" >> $env:GITHUB_OUTPUT | |
| } | |
| - name: Push to Chocolatey | |
| if: steps.check_choco_key.outputs.has_key == 'true' | |
| run: | | |
| $VERSION = "${{ steps.package-version.outputs.version }}" | |
| cd choco-build | |
| choco apikey --key "${{ secrets.CHOCOLATEY_API_KEY }}" --source https://push.chocolatey.org/ | |
| try { | |
| choco push "termix-ssh.$VERSION.nupkg" --source https://push.chocolatey.org/ | |
| if ($LASTEXITCODE -eq 0) { | |
| } else { | |
| throw "Chocolatey push failed with exit code $LASTEXITCODE" | |
| } | |
| } catch { | |
| } | |
| - name: Upload Chocolatey package as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: chocolatey-package | |
| path: choco-build/*.nupkg | |
| retention-days: 30 | |
| submit-to-flatpak: | |
| runs-on: ubuntu-latest | |
| if: github.event.inputs.artifact_destination == 'submit' | |
| needs: [build-linux] | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| RELEASE_DATE=$(date +%Y-%m-%d) | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "release_date=$RELEASE_DATE" >> $GITHUB_OUTPUT | |
| - name: Download Linux x64 AppImage artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: termix_linux_x64_appimage | |
| path: artifact-x64 | |
| - name: Download Linux arm64 AppImage artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: termix_linux_arm64_appimage | |
| path: artifact-arm64 | |
| - name: Get AppImage file info | |
| id: appimage-info | |
| run: | | |
| VERSION="${{ steps.package-version.outputs.version }}" | |
| APPIMAGE_X64_FILE=$(find artifact-x64 -name "*.AppImage" -type f | head -n 1) | |
| APPIMAGE_X64_NAME=$(basename "$APPIMAGE_X64_FILE") | |
| CHECKSUM_X64=$(sha256sum "$APPIMAGE_X64_FILE" | awk '{print $1}') | |
| APPIMAGE_ARM64_FILE=$(find artifact-arm64 -name "*.AppImage" -type f | head -n 1) | |
| APPIMAGE_ARM64_NAME=$(basename "$APPIMAGE_ARM64_FILE") | |
| CHECKSUM_ARM64=$(sha256sum "$APPIMAGE_ARM64_FILE" | awk '{print $1}') | |
| echo "appimage_x64_name=$APPIMAGE_X64_NAME" >> $GITHUB_OUTPUT | |
| echo "checksum_x64=$CHECKSUM_X64" >> $GITHUB_OUTPUT | |
| echo "appimage_arm64_name=$APPIMAGE_ARM64_NAME" >> $GITHUB_OUTPUT | |
| echo "checksum_arm64=$CHECKSUM_ARM64" >> $GITHUB_OUTPUT | |
| - name: Install ImageMagick for icon generation | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y imagemagick | |
| - name: Prepare Flatpak submission files | |
| run: | | |
| VERSION="${{ steps.package-version.outputs.version }}" | |
| CHECKSUM_X64="${{ steps.appimage-info.outputs.checksum_x64 }}" | |
| CHECKSUM_ARM64="${{ steps.appimage-info.outputs.checksum_arm64 }}" | |
| RELEASE_DATE="${{ steps.package-version.outputs.release_date }}" | |
| APPIMAGE_X64_NAME="${{ steps.appimage-info.outputs.appimage_x64_name }}" | |
| APPIMAGE_ARM64_NAME="${{ steps.appimage-info.outputs.appimage_arm64_name }}" | |
| mkdir -p flatpak-submission | |
| cp flatpak/com.karmaa.termix.yml flatpak-submission/ | |
| cp flatpak/com.karmaa.termix.desktop flatpak-submission/ | |
| cp flatpak/com.karmaa.termix.metainfo.xml flatpak-submission/ | |
| cp flatpak/flathub.json flatpak-submission/ | |
| cp public/icon.svg flatpak-submission/com.karmaa.termix.svg | |
| convert public/icon.png -resize 256x256 flatpak-submission/icon-256.png | |
| convert public/icon.png -resize 128x128 flatpak-submission/icon-128.png | |
| sed -i "s/VERSION_PLACEHOLDER/$VERSION/g" flatpak-submission/com.karmaa.termix.yml | |
| sed -i "s/CHECKSUM_X64_PLACEHOLDER/$CHECKSUM_X64/g" flatpak-submission/com.karmaa.termix.yml | |
| sed -i "s/CHECKSUM_ARM64_PLACEHOLDER/$CHECKSUM_ARM64/g" flatpak-submission/com.karmaa.termix.yml | |
| sed -i "s/VERSION_PLACEHOLDER/$VERSION/g" flatpak-submission/com.karmaa.termix.metainfo.xml | |
| sed -i "s/DATE_PLACEHOLDER/$RELEASE_DATE/g" flatpak-submission/com.karmaa.termix.metainfo.xml | |
| - name: List submission files | |
| run: | | |
| ls -la flatpak-submission/ | |
| - name: Upload Flatpak submission as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: flatpak-submission | |
| path: flatpak-submission/* | |
| retention-days: 30 | |
| submit-to-homebrew: | |
| runs-on: macos-latest | |
| if: github.event.inputs.artifact_destination == 'submit' | |
| needs: [build-macos] | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 1 | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Download macOS Universal DMG artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: termix_macos_universal_dmg | |
| path: artifact | |
| - name: Get DMG file info | |
| id: dmg-info | |
| run: | | |
| VERSION="${{ steps.package-version.outputs.version }}" | |
| DMG_FILE=$(find artifact -name "*.dmg" -type f | head -n 1) | |
| DMG_NAME=$(basename "$DMG_FILE") | |
| CHECKSUM=$(shasum -a 256 "$DMG_FILE" | awk '{print $1}') | |
| echo "dmg_name=$DMG_NAME" >> $GITHUB_OUTPUT | |
| echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT | |
| - name: Prepare Homebrew submission files | |
| run: | | |
| VERSION="${{ steps.package-version.outputs.version }}" | |
| CHECKSUM="${{ steps.dmg-info.outputs.checksum }}" | |
| DMG_NAME="${{ steps.dmg-info.outputs.dmg_name }}" | |
| mkdir -p homebrew-submission/Casks/t | |
| cp homebrew/termix.rb homebrew-submission/Casks/t/termix.rb | |
| cp homebrew/README.md homebrew-submission/ | |
| sed -i '' "s/VERSION_PLACEHOLDER/$VERSION/g" homebrew-submission/Casks/t/termix.rb | |
| sed -i '' "s/CHECKSUM_PLACEHOLDER/$CHECKSUM/g" homebrew-submission/Casks/t/termix.rb | |
| - name: Verify Cask syntax | |
| run: | | |
| if ! command -v brew &> /dev/null; then | |
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| fi | |
| ruby -c homebrew-submission/Casks/t/termix.rb | |
| - name: List submission files | |
| run: | | |
| find homebrew-submission -type f | |
| - name: Upload Homebrew submission as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: homebrew-submission | |
| path: homebrew-submission/* | |
| retention-days: 30 | |
| upload-to-release: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| if: github.event.inputs.artifact_destination == 'release' | |
| needs: [build-windows, build-linux, build-macos] | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Get latest release tag | |
| id: get_release | |
| run: | | |
| echo "RELEASE_TAG=$(gh release list --repo ${{ github.repository }} --limit 1 --json tagName -q '.[0].tagName')" >> $GITHUB_ENV | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - name: Display artifact structure | |
| run: | | |
| ls -R artifacts/ | |
| - name: Upload artifacts to latest release | |
| run: | | |
| cd artifacts | |
| for dir in */; do | |
| cd "$dir" | |
| for file in *; | |
| do | |
| if [ -f "$file" ]; then | |
| gh release upload "$RELEASE_TAG" "$file" --repo ${{ github.repository }} --clobber | |
| fi | |
| done | |
| cd .. | |
| done | |
| env: | |
| GH_TOKEN: ${{ github.token }} |