Skip to content

Bump Electron to 32.3.3 #2295

Bump Electron to 32.3.3

Bump Electron to 32.3.3 #2295

Workflow file for this run

name: Build Pulsar Binaries
on:
push:
branches:
- 'master'
tags:
- '**'
pull_request:
workflow_dispatch:
env:
# Variables needed for build information
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PYTHON_VERSION: '3.12'
ROLLING_UPLOAD_TOKEN: ${{ secrets.ROLLING_RELEASE_UPLOAD_TOKEN }}
# Below variables allow us to quickly control visual tests for each platform
RUN_WINDOWS_VT: false
RUN_LINUX_VT: true
RUN_MACOS_VT: true
jobs:
build:
strategy:
matrix:
os: [ macos-14, ubuntu-24.04-arm, ubuntu-latest, windows-2022 ]
node-architecture: [ '' ]
include:
- os: macos-14
node-architecture: x64
- os: ubuntu-24.04-arm
image: "debian:11"
- os: ubuntu-latest
image: "debian:11"
fail-fast: false
runs-on: ${{ matrix.os }}
container: ${{ matrix.image }}
outputs:
timestamp: ${{ steps.linux-binary-version.outputs.timestamp }}
steps:
# We want to build against the oldest version of `glibc` that we can get
# away with. (As of Electron 32, Electron themselves build with a Debian
# 11 image, so the version we target is `glibc` 2.31.) But at some point
# in the recent past, V8 started enforcing use of a compiler that
# understands C++20, and this started affecting Pulsar once it bumped
# past a certain version of Electron.
#
# Debian 11 gives us the `glibc` we want, but its `gcc` doesn't fit the
# bill. (Its C++20 support is experimental and we were never able to make
# it play well with Electron after the v32 bump.)
#
# For this reason, dependencies will build just fine upon initial
# installation, but run the risk of failing when we rebuild them for
# Electron. Electron's V8 version tends to be driven by Chromium; so even
# though Electron 32.2.3 uses Node 20.18.1, it combines it with a much
# higher version of V8 than the standalone Node 20.18.1 used. For this
# exact reason, even a dependency like `@pulsar-edit/fuzzy-native`, which
# builds perfectly well on Node 20.18.1 with C++17, fails at the rebuild
# step because of V8's more stringent requirements.
#
# The way out of this is to decouple the target `glibc` from that of the
# host machine — allowing us to use newer `gcc` on Debian 11 without
# raising the `glibc` floor above 2.31. To do this, we install
# conda-forge's vendored static toolchain.
#
# And since Electron is the only thing mandating C++20 support at the
# moment (the relevant libraries we use still build just fine with C++17
# or less), for now we'll only use these vendored tools for the
# electron-rebuild step. If we should need to use them more widely after
# a future Electron bump, it should be as simple as pointing the relevant
# environment variables to `PULSAR_CC`, `PULSAR_CXX`, etc., for whichever
# other steps require them.
#
# (For instance: the version of V8 that first caused rebuild failures for
# us was 12.8; Node itself didn't start using a version that high until
# 23.0.0. So once we bump to a version of Electron that uses Node 24, I
# expect that we'll need to start using the conda-forge compiler
# toolchain throughout this workflow file. At that point, we should also
# research whether it's worth bumping to a newer Debian image; we don't
# want to set a _higher_ `glibc` floor than Electron themselves, but
# there's no point in targeting a _lower_ `glibc` floor, either. Ideally,
# we'd stay in sync with whatever version of Debian Electron uses for
# Linux builds.)
- name: Install Modern GCC Toolchain - Linux
if: ${{ runner.os == 'Linux' }}
run: |
apt-get update && apt-get install -y curl bzip2
if [ "${{ runner.arch }}" = "ARM64" ]; then
MAMBA_ARCH=linux-aarch64
CONDA_TARGET=aarch64-conda-linux-gnu
MULTIARCH=aarch64-linux-gnu
else
MAMBA_ARCH=linux-64
CONDA_TARGET=x86_64-conda-linux-gnu
MULTIARCH=x86_64-linux-gnu
fi
curl -Ls "https://micro.mamba.pm/api/micromamba/${MAMBA_ARCH}/latest" | tar -xvj -C /usr/local bin/micromamba
/usr/local/bin/micromamba create -y -p /opt/gcc-toolchain -c conda-forge gcc=12 gxx=12
echo "PULSAR_CC=/opt/gcc-toolchain/bin/${CONDA_TARGET}-gcc" >> "$GITHUB_ENV"
echo "PULSAR_CXX=/opt/gcc-toolchain/bin/${CONDA_TARGET}-g++" >> "$GITHUB_ENV"
echo "PULSAR_CFLAGS=-I/usr/include -I/usr/include/${MULTIARCH}" >> "$GITHUB_ENV"
echo "PULSAR_CXXFLAGS=-I/usr/include -I/usr/include/${MULTIARCH}" >> "$GITHUB_ENV"
echo "PULSAR_LDFLAGS=-L/usr/lib/${MULTIARCH} -L/usr/lib" >> "$GITHUB_ENV"
- name: Install build dependencies - Linux
if: ${{ runner.os == 'Linux' }}
run: apt-get update && apt-get install -y git python3 python3-pip make gcc g++ file libx11-dev libxkbfile-dev pkg-config libsecret-1-dev rpm xvfb ffmpeg zstd wget squashfs-tools libwayland-dev libwayland-client0 libxkbcommon-dev libxkbcommon-x11-dev libxkbcommon0 xkb-data
libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev # <-- Python-related stuff on this line
- name: Restore Compiled Python from Cache - Linux
if: ${{ runner.os == 'Linux' }}
id: compiled-python-restore
uses: actions/cache/restore@v5
with:
key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.image }}-Python-${{ env.PYTHON_VERSION }}.9
path: Python-${{ env.PYTHON_VERSION }}.9
- name: Compile Python - Linux
if: ${{ runner.os == 'Linux' && steps.compiled-python-restore.outputs.cache-hit != 'true' }}
run: |
wget "https://www.python.org/ftp/python/${PYTHON_VERSION}.9/Python-${PYTHON_VERSION}.9.tgz"
echo "45313e4c5f0e8acdec9580161d565cf5fea578e3eabf25df7cc6355bf4afa1ee Python-${PYTHON_VERSION}.9.tgz" | sha256sum --check
tar xzf "Python-${PYTHON_VERSION}.9.tgz"
cd "Python-${PYTHON_VERSION}.9"
./configure --enable-optimizations
make
- name: Save Compiled Python to Cache - Linux
if: ${{ runner.os == 'Linux' && steps.compiled-python-restore.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v5
with:
key: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.image }}-Python-${{ env.PYTHON_VERSION }}.9
path: Python-${{ env.PYTHON_VERSION }}.9
- name: Install Compiled Python - Linux
if: ${{ runner.os == 'Linux' }}
run: cd "Python-${PYTHON_VERSION}.9" && make install
- name: Checkout the latest code
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
architecture: ${{ matrix.node-architecture }}
- name: Setup Python
# actions/setup-python's copy of Python is compiled for too new glibc,
# which won't work in a Debian 10 Docker image.
# Get Python from apt repos instead on Linux.
if: ${{ runner.os != 'Linux' }}
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install Python setuptools
# This is needed for Python 3.12+, since many versions of node-gyp
# are incompatible with Python 3.12+, which no-longer ships 'distutils'
# out of the box. 'setuptools' package provides 'distutils'.
run: python3 -m pip install setuptools
- name: Install Yarn - Linux
if: ${{ runner.os == 'Linux' }}
run: npm install -g yarn
- name: Setup Git Submodule
if: ${{ runner.os != 'Linux' }}
run: |
git submodule init
git submodule update
- name: Setup Git Submodule - Linux
if: ${{ runner.os == 'Linux' }}
run: |
git config --global --add safe.directory /__w/pulsar/pulsar
git submodule init
git submodule update
- name: Set Timestamp for Binary Version - Linux
id: linux-binary-version
if: ${{ runner.os == 'Linux' }}
# This output is currently only set for the sake of the Rolling binary upload script.
# See the "test-and-upload-Linux" job below.
run: echo "timestamp=`date -u +%Y%m%d%H`" >> "$GITHUB_OUTPUT"
- name: Check Pulsar Version
if: ${{ runner.os != 'Windows' }}
run: sed -i -e "s/[0-9]*-dev/`date -u +%Y%m%d%H`/g" package.json
- name: Check Pulsar Version - Windows
if: ${{ runner.os == 'Windows' }}
run: (Get-Content package.json) -replace '[0-9]*-dev', (date -u +%Y%m%d%H) | Set-Content -Path package.json
- name: Reinstall Current Node-GYP NodeJS Headers
# Overwrite bad headers that get downloaded.
# NodeJS versions above 16 should come with `node-gyp@9.4.0` that has a fix
# for this issue. At that point this additional step can be removed.
run: npx node-gyp install ${{ env.NODE_VERSION }}
- name: Explicitly Specify Python Path (Windows)
if: ${{ runner.os == 'Windows' }}
# The Windows image somehow gets confused about which Python it should
# use. Here we set the `PYTHON` env variable to whatever we get when we
# run `python3` in a shell, since that's the copy we used to install
# `setuptools` above.
run: |
Get-Command python3 | Format-Wide -Property Source
$pythonPath = (Get-Command python3)[0].Source
echo "PYTHON=$pythonPath" >> $env:GITHUB_ENV
- name: Install Windows 10 SDK via Visual Studio
if: ${{ runner.os == 'Windows' }}
working-directory: 'C:\Program Files (x86)\Microsoft Visual Studio\Installer'
run: |
.\vs_installer.exe modify --installPath "C:\Program Files\Microsoft Visual Studio\2022\Enterprise" --add Microsoft.VisualStudio.Component.Windows10SDK.19041 --quiet --norestart --nocache | Out-Host
# Slight funk here, the command will act async if we don't wait for it's result. `--wait` isn't supported on `vs_installer.exe`
# So we use the pipe to ensure we wait for output, but for the LIFE (#1350) I can't get output here.
- name: Install Pulsar Dependencies
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: yarn install --ignore-engines
on_retry_command: rm -R node_modules
- name: Rebuild Pulsar Dependencies for Electron (non-Linux)
if: ${{ runner.os != 'Linux' }}
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: yarn build
- name: Rebuild Pulsar Dependencies for Electron (Linux)
if: ${{ runner.os == 'Linux' }}
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
env:
CC: ${{ env.PULSAR_CC }}
CXX: ${{ env.PULSAR_CXX }}
CFLAGS: ${{ env.PULSAR_CFLAGS }}
CXXFLAGS: ${{ env.PULSAR_CXXFLAGS }}
LDFLAGS: ${{ env.PULSAR_LDFLAGS }}
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: |
yarn build
- name: Build ppm
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: yarn build:apm
- name: Cache Pulsar dependencies - Linux
if: ${{ runner.os == 'Linux' }}
uses: actions/cache/save@v5
with:
path: |
node_modules
packages
key: Linux-dependencies-${{ runner.arch }}-${{ github.sha }}-${{ github.workflow }}
# macOS Signing Stuff
- name: Build Pulsar Binaries (macOS) (Signed)
if: ${{ runner.os == 'macOS' && github.event_name == 'push' }}
# Note: PRs generated from forks cannot access GitHub Secrets.
# So if the PR is from a fork, we can still build, but cannot sign.
# Note: We aren't attempting to sign for *any* PRs anymore, though.
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPLEID: ${{ secrets.APPLEID }}
APPLEID_PASSWORD: ${{ secrets.APPLEID_PASSWORD }}
TEAM_ID: ${{ secrets.TEAM_ID }}
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
with:
timeout_minutes: 31
max_attempts: 7
command: yarn dist
- name: Build Pulsar Binaries (macOS) (Unsigned)
if: ${{ runner.os == 'macOS' && github.event_name != 'push' }}
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
with:
timeout_minutes: 31
max_attempts: 7
command: yarn dist
- name: Build Pulsar Binaries
if: ${{ runner.os != 'macOS' }}
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: yarn dist
- name: Rename Pulsar Binaries for Regular release (ARM64 Linux)
if: ${{ runner.os == 'Linux' && runner.arch == 'ARM64' }}
run: node ./script/rename.js "ARM.Linux"
- name: Rename Pulsar Binaries for Regular release (x64 Linux)
if: ${{ runner.os == 'Linux' && runner.arch == 'X64' }}
run: node ./script/rename.js "Linux"
- name: Rename Pulsar Binaries for Regular release (ARM64 macOS)
if: ${{ runner.os == 'macOS' && runner.arch == 'ARM64' && matrix.node-architecture != 'x64' }}
run: node ./script/rename.js "Silicon.Mac"
- name: Rename Pulsar Binaries for Regular release (x64 macOS)
if: ${{ runner.os == 'macOS' && ( runner.arch == 'X64' || matrix.node-architecture == 'x64' ) }}
run: node ./script/rename.js "Intel.Mac"
- name: Rename Pulsar Binaries for Regular release (Windows)
if: ${{ runner.os == 'Windows' }}
run: node ./script/rename.js "Windows"
- name: Fix AppImage target - x64 Linux
if: ${{ runner.os == 'Linux' && runner.arch == 'X64' }}
run: ./script/fix-linux-appimage.sh x86_64
- name: Fix AppImage target - ARM64 Linux
if: ${{ runner.os == 'Linux' && runner.arch == 'ARM64' }}
run: ./script/fix-linux-appimage.sh ARM_64
- name: Cache Pulsar Binaries - Linux
if: ${{ runner.os == 'Linux' }}
uses: actions/cache/save@v5
with:
path: ./binaries
key: pulsar-Linux-Binaries-${{ runner.arch }}-${{ github.sha }}-${{ github.workflow }}
- name: Upload Binary Artifacts
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }} ${{ matrix.node-architecture }} Binaries
path: ./binaries/*
- name: Test Binary - Windows
if: runner.os == 'Windows' && env.RUN_WINDOWS_VT == true
# TODO: Convert script to PowerShell
run: |
mkdir extracted; tar -xf binaries/*zip -C ./extracted/
export BINARY_NAME=./extracted/Pulsar.exe
PLAYWRIGHT_JUNIT_OUTPUT_NAME=report.xml npx playwright test --reporter=junit,list || echo "Yeah, tests failed, Windows is like this"
- name: Test Binary - macOS
if: runner.os == 'macOS' && env.RUN_MACOS_VT == true
run: |
export PATH="/usr/local/opt/node@16/bin:/usr/local/bin:$PATH"
rm -R node_modules/electron; yarn install --check-files
hdiutil mount binaries/*Pulsar*dmg
export BINARY_NAME=`ls /Volumes/Pulsar*/Pulsar.app/Contents/MacOS/Pulsar`
PLAYWRIGHT_JUNIT_OUTPUT_NAME=report.xml arch -x86_64 npx playwright test --reporter=junit,list
- name: Add binaries to Rolling Release Repo
if: ${{ github.event_name == 'push' && runner.os != 'Linux' }}
# We only want to upload rolling binaries if they are a commit to master
# Otherwise we want to not upload if it's a PR or manually triggered build
run: |
cd ./script/rolling-release-scripts
npm install
node ./rolling-release-binary-upload.js
- name: Upload Video Artifacts
# Run whether this job passed or failed, unless explicitly cancelled.
if: ${{ !cancelled() && runner.os != 'Linux' }}
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }} Videos
path: ./tests/videos/**
test-and-upload-Linux:
# I couldn't figure out how to get these visual tests to actually run in the
# Debian Docker environment. If anyone can make it work, feel free to
# re-combine visual testing on Linux back into the main build job above!
# - DeeDeeG
strategy:
matrix:
os: [ ubuntu-24.04-arm, ubuntu-latest ]
fail-fast: false
runs-on: ${{ matrix.os }}
needs: build
steps:
- name: Install build dependencies - Linux
if: ${{ runner.os == 'Linux' }}
run: sudo apt-get update && sudo apt-get install -y git python3 python3-pip make gcc g++ file libx11-dev libxkbfile-dev pkg-config libsecret-1-dev rpm xvfb ffmpeg zstd wget squashfs-tools libwayland-dev libwayland-client0 libxkbcommon-dev libxkbcommon-x11-dev libxkbcommon0 xkb-data
- name: Checkout the latest code
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: Restore Cached Pulsar Binaries - Linux
if: ${{ runner.os == 'Linux' }}
uses: actions/cache/restore@v5
with:
path: ./binaries
key: pulsar-Linux-Binaries-${{ runner.arch }}-${{ github.sha }}-${{ github.workflow }}
- name: Restore Cached Pulsar dependencies - Linux
if: ${{ runner.os == 'Linux' }}
uses: actions/cache/restore@v5
with:
path: |
node_modules
packages
key: Linux-dependencies-${{ runner.arch }}-${{ github.sha }}-${{ github.workflow }}
- name: Test Binary - Linux
if: ${{ (runner.os == 'Linux') && env.RUN_LINUX_VT }}
run: |
rm -R node_modules/electron; yarn install --check-files
./binaries/*AppImage --appimage-extract
export BINARY_NAME='squashfs-root/pulsar'
mkdir -p ./tests/videos
Xvfb -screen 0 1024x768x24+32 :99 & nohup ffmpeg -video_size 1024x768 -f x11grab -i :99.0 ./tests/videos/out.mpg & DISPLAY=:99 PLAYWRIGHT_JUNIT_OUTPUT_NAME=report.xml npx playwright test --reporter=junit,list
- name: Check Pulsar Version
if: ${{ runner.os != 'Windows' }}
run: sed -i -e "s/[0-9]*-dev/${TIMESTAMP}/g" package.json
env:
TIMESTAMP: ${{needs.build.outputs.timestamp}}
- name: Add binaries to Rolling Release Repo - Linux
if: ${{ github.event_name == 'push' && runner.os == 'Linux' }}
# We only want to upload rolling binaries if they are a commit to master
# Otherwise we want to not upload if it's a PR or manually triggered build
run: |
cd ./script/rolling-release-scripts
npm install
node ./rolling-release-binary-upload.js
- name: Upload Video Artifacts - Linux
# Run whether this job passed or failed, unless explicitly cancelled.
if: ${{ !cancelled() && runner.os == 'Linux' }}
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }} Videos
path: ./tests/videos/**