Build Distributions #68
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 Distributions | |
on: | |
push: | |
tags: | |
- '*' | |
workflow_dispatch: | |
jobs: | |
build-apple: | |
name: Build macOS (Apple Silicon) | |
runs-on: macos-latest | |
environment: "mac build" | |
outputs: | |
version: ${{ steps.get-version.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get version from package.json | |
id: get-version | |
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT | |
- name: Validate version consistency | |
run: | | |
PACKAGE_VERSION="${{ steps.get-version.outputs.version }}" | |
TAG_NAME="${{ github.ref_name }}" | |
# Check if both are semantic versions (x.y.z format) | |
if [[ $PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ $TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "Both package.json version ($PACKAGE_VERSION) and tag ($TAG_NAME) are semantic versions" | |
if [ "$PACKAGE_VERSION" != "$TAG_NAME" ]; then | |
echo "ERROR: Version mismatch!" | |
echo "package.json version: $PACKAGE_VERSION" | |
echo "Git tag version: $TAG_NAME" | |
exit 1 | |
else | |
echo "✅ Versions match: $PACKAGE_VERSION" | |
fi | |
else | |
echo "Skipping version validation - not both semantic versions" | |
echo "package.json: $PACKAGE_VERSION" | |
echo "tag: $TAG_NAME" | |
fi | |
- name: Configure Node caching | |
uses: actions/cache@v4 | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: ${{ runner.os }}-npm- | |
- name: Install dependencies | |
run: npm install | |
- name: Run tests | |
run: npm test | |
timeout-minutes: 5 | |
- name: Build distribution (macOS ARM) | |
env: | |
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} | |
CSC_LINK: ${{ secrets.CSC_LINK }} | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: npm run build:mac | |
- name: Create README | |
run: | | |
echo "More information: https://github.com/jeremybmerrill/meaningfully" > dist/README.txt | |
- name: Upload artifact (macOS) | |
id: upload | |
uses: actions/upload-artifact@v4 | |
with: | |
name: meaningfully-macOS | |
path: | | |
dist/meaningfully-${{ steps.get-version.outputs.version }}.arm64.dmg | |
dist/README.txt | |
build-intel: | |
name: Build macOS (Intel) | |
runs-on: macos-13 | |
environment: "mac build" | |
outputs: | |
version: ${{ steps.get-version.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get version from package.json | |
id: get-version | |
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT | |
- name: Validate version consistency | |
run: | | |
PACKAGE_VERSION="${{ steps.get-version.outputs.version }}" | |
TAG_NAME="${{ github.ref_name }}" | |
# Check if both are semantic versions (x.y.z format) | |
if [[ $PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ $TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "Both package.json version ($PACKAGE_VERSION) and tag ($TAG_NAME) are semantic versions" | |
if [ "$PACKAGE_VERSION" != "$TAG_NAME" ]; then | |
echo "ERROR: Version mismatch!" | |
echo "package.json version: $PACKAGE_VERSION" | |
echo "Git tag version: $TAG_NAME" | |
exit 1 | |
else | |
echo "✅ Versions match: $PACKAGE_VERSION" | |
fi | |
else | |
echo "Skipping version validation - not both semantic versions" | |
echo "package.json: $PACKAGE_VERSION" | |
echo "tag: $TAG_NAME" | |
fi | |
- name: Configure Node caching | |
uses: actions/cache@v4 | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: ${{ runner.os }}-npm- | |
- name: Install brew dependencies | |
run: brew install pkg-config cairo pango libjpeg giflib librsvg | |
- name: Install npm deps | |
run: npm install | |
- name: Run tests | |
run: npm test | |
timeout-minutes: 5 | |
- name: Build distribution (macOS Intel) | |
env: | |
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} | |
CSC_LINK: ${{ secrets.CSC_LINK }} | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: npm run build:mac -- --publish always | |
- name: Create README | |
run: 'echo "More information: https://github.com/jeremybmerrill/meaningfully" > dist/README.txt' | |
- name: Upload artifact (macOS Intel) | |
id: upload | |
uses: actions/upload-artifact@v4 | |
with: | |
name: meaningfully-macOS-intel | |
path: | | |
dist/meaningfully-${{ steps.get-version.outputs.version }}.x64.dmg | |
dist/README.txt | |
build-windows: | |
name: Build Windows | |
runs-on: windows-latest | |
environment: "mac build" | |
outputs: | |
version: ${{ steps.get-version.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get version from package.json | |
id: get-version | |
run: echo "version=$(node -p "require('./package.json').version")" >> $env:GITHUB_OUTPUT | |
- name: Validate version consistency | |
run: | | |
PACKAGE_VERSION="${{ steps.get-version.outputs.version }}" | |
TAG_NAME="${{ github.ref_name }}" | |
# Check if both are semantic versions (x.y.z format) | |
if [[ $PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ $TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "Both package.json version ($PACKAGE_VERSION) and tag ($TAG_NAME) are semantic versions" | |
if [ "$PACKAGE_VERSION" != "$TAG_NAME" ]; then | |
echo "ERROR: Version mismatch!" | |
echo "package.json version: $PACKAGE_VERSION" | |
echo "Git tag version: $TAG_NAME" | |
exit 1 | |
else | |
echo "✅ Versions match: $PACKAGE_VERSION" | |
fi | |
else | |
echo "Skipping version validation - not both semantic versions" | |
echo "package.json: $PACKAGE_VERSION" | |
echo "tag: $TAG_NAME" | |
fi | |
- name: Setup Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '20' # Or your specific Node.js version | |
cache: 'npm' | |
# Keep your MSYS2 setup for GTK and other build tools, but ensure it's | |
# installing the correct GTK version (GTK3 is generally preferred for modern canvas) | |
- name: Setup MSYS2 and GTK | |
uses: msys2/setup-msys2@v2 | |
with: | |
msystem: MINGW64 | |
update: true | |
install: >- | |
mingw-w64-x86_64-gtk3 | |
mingw-w64-x86_64-pkg-config | |
mingw-w64-x86_64-cairo | |
mingw-w64-x86_64-pango | |
mingw-w64-x86_64-libjpeg-turbo | |
mingw-w64-x86_64-giflib | |
mingw-w64-x86_64-librsvg | |
base-devel | |
gcc | |
mingw-w64-x86_64-gcc | |
- name: Add MSYS2 and GTK to PATH and set env vars | |
shell: pwsh | |
run: | | |
# Add MSYS2 paths | |
echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
echo "C:\msys64\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
# These environment variables are crucial for node-gyp/pkg-config to find libs | |
echo "PKG_CONFIG_PATH=C:\msys64\mingw64\lib\pkgconfig" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
echo "C_INCLUDE_PATH=C:\msys64\mingw64\include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
echo "LIBRARY_PATH=C:\msys64\mingw64\lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
# **Crucial for canvas:** Set GTK_Root if canvas expects it in a specific location | |
# The errors indicate it's looking in C:\GTK\bin | |
# We need to link C:\msys64\mingw64 to C:\GTK or tell canvas where GTK is. | |
# A common fix is to create a symlink or manually copy if symlinks are an issue. | |
# Or, better, pass --GTK_Root to node-gyp if possible (electron-builder might not expose this easily). | |
# Let's try explicitly setting a GTK_Root env var if node-pre-gyp might pick it up. | |
# As a fallback, you could try copying the GTK files to C:\GTK | |
# This might be the culprit for "Missing input files: C:\GTK\bin\zlib1.dll" | |
echo "GTK_Root=C:\msys64\mingw64" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
# Diagnostic: Check if GTK DLLs are where canvas expects | |
Write-Host "Checking for GTK DLLs in C:\msys64\mingw64\bin" | |
Get-ChildItem "C:\msys64\mingw64\bin\*.dll" | Select-Object -First 10 | Format-Table Name | |
- name: Setup GTK symlink | |
run: | | |
New-Item -ItemType Directory -Force -Path "C:\GTK" | |
New-Item -ItemType SymbolicLink -Path "C:\GTK\bin" -Target "C:\msys64\mingw64\bin" | |
shell: powershell | |
- name: Install dependencies with GTK path | |
run: npm install --build-from-source --GTK_Root=C:\msys64\mingw64 | |
shell: cmd | |
- name: Run tests | |
run: npm test | |
timeout-minutes: 5 | |
- name: Build distribution (Windows) | |
env: | |
WIN_CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} | |
WIN_CSC_LINK: ${{ secrets.CSC_LINK }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# Ensure PATH includes MSYS2 bins for electron-builder if needed | |
PATH: "C:\\msys64\\mingw64\\bin;C:\\msys64\\usr\\bin;${{ env.PATH }}" | |
run: npm run build:win -- --publish always | |
- name: Create README | |
run: 'echo "More information: https://github.com/jeremybmerrill/meaningfully" > dist\README.txt' | |
- name: ls dist | |
run: 'ls dist/' | |
- name: Upload artifact (Windows) | |
uses: actions/upload-artifact@v4 | |
with: | |
name: meaningfully-windows | |
path: | | |
dist/meaningfully-${{ steps.get-version.outputs.version }}-setup.exe | |
dist/meaningfully-${{ steps.get-version.outputs.version }}-setup.exe.blockmap | |
dist\README.txt | |
build-linux: | |
name: Build Linux | |
runs-on: ubuntu-latest | |
environment: "mac build" | |
outputs: | |
version: ${{ steps.get-version.outputs.version }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get version from package.json | |
id: get-version | |
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT | |
- name: Validate version consistency | |
run: | | |
PACKAGE_VERSION="${{ steps.get-version.outputs.version }}" | |
TAG_NAME="${{ github.ref_name }}" | |
# Check if both are semantic versions (x.y.z format) | |
if [[ $PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ $TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
echo "Both package.json version ($PACKAGE_VERSION) and tag ($TAG_NAME) are semantic versions" | |
if [ "$PACKAGE_VERSION" != "$TAG_NAME" ]; then | |
echo "ERROR: Version mismatch!" | |
echo "package.json version: $PACKAGE_VERSION" | |
echo "Git tag version: $TAG_NAME" | |
exit 1 | |
else | |
echo "✅ Versions match: $PACKAGE_VERSION" | |
fi | |
else | |
echo "Skipping version validation - not both semantic versions" | |
echo "package.json: $PACKAGE_VERSION" | |
echo "tag: $TAG_NAME" | |
fi | |
- name: Configure Node caching | |
uses: actions/cache@v4 | |
with: | |
path: ~/.npm | |
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} | |
restore-keys: ${{ runner.os }}-npm- | |
- name: Install Linux Build Dependencies | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev libarchive-tools libfuse2 libgtk-3-0 libnss3 libxshmfence1 libatk-bridge2.0-0 libx11-xcb1 libxcb-dri3-0 libxcomposite1 libxcursor1 libxdamage1 libxfixes3 libxi6 libxrandr2 libxtst6 libgbm1 libpangocairo-1.0-0 libpango-1.0-0 libcairo2 libatspi2.0-0 | |
sudo snap install snapcraft --classic | |
- name: Install dependencies | |
run: npm install | |
- name: Run tests | |
run: npm test | |
timeout-minutes: 5 | |
- name: Build distribution (Linux) | |
env: | |
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} | |
CSC_LINK: ${{ secrets.CSC_LINK }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} | |
run: npm run build:linux -- --publish always | |
# - name: Run integration tests | |
# run: | | |
# mkdir -p screenshots | |
# npm run wdio | |
# continue-on-error: true # So we can upload screenshots even if tests fail | |
# - name: Upload test failure screenshots | |
# if: failure() || success() # Upload screenshots regardless of test outcome | |
# uses: actions/upload-artifact@v4 | |
# with: | |
# name: test-failure-screenshots | |
# path: screenshots/*.png | |
# retention-days: 30 | |
# if-no-files-found: ignore | |
- name: Create README | |
run: 'echo "More information: https://github.com/jeremybmerrill/meaningfully" > dist/README.txt' | |
- name: ls dist | |
run: 'ls dist/' | |
- name: Upload artifact (Linux) | |
uses: actions/upload-artifact@v4 | |
with: | |
name: meaningfully-linux | |
# add back later under path. dist/meaningfully-${{ steps.get-version.outputs.version }}.snap | |
path: | | |
dist/meaningfully-${{ steps.get-version.outputs.version }}.deb | |
dist/meaningfully-${{ steps.get-version.outputs.version }}.AppImage | |
dist/meaningfully-${{ steps.get-version.outputs.version }}.snap | |
dist/README.txt | |
release: | |
name: Create GitHub Release | |
runs-on: ubuntu-latest | |
environment: "mac build" | |
needs: | |
- build-apple | |
- build-intel | |
- build-windows | |
- build-linux | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get version from build job | |
id: get-version | |
run: echo "version=${{ needs.build-apple.outputs.version }}" >> $GITHUB_OUTPUT | |
- name: Download macOS artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: meaningfully-macOS | |
path: ./artifacts/macOS | |
- name: Download macOS (Intel) artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: meaningfully-macOS-intel | |
path: ./artifacts/macOS-intel | |
- name: Download Linux artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: meaningfully-linux | |
path: ./artifacts/linux | |
- name: Download Windows artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: meaningfully-windows | |
path: ./artifacts/windows | |
- name: Create Release | |
uses: softprops/action-gh-release@v2 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: ${{ github.ref_name == 'main' && 'manualrelease' || github.ref_name }} | |
name: Release ${{ github.ref_name == 'main' && 'manualrelease' || github.ref_name }} | |
draft: false | |
prerelease: false | |
# add back later under files: ./artifacts/linux/meaningfully-${{ steps.get-version.outputs.version }}.snap | |
files: | | |
./artifacts/linux/meaningfully-${{ steps.get-version.outputs.version }}.deb | |
./artifacts/linux/meaningfully-${{ steps.get-version.outputs.version }}.AppImage | |
./artifacts/linux/meaningfully-${{ steps.get-version.outputs.version }}.snap | |
./artifacts/macOS-intel/meaningfully-${{ steps.get-version.outputs.version }}.x64.dmg | |
./artifacts/macOS/meaningfully-${{ steps.get-version.outputs.version }}.arm64.dmg | |
./artifacts/windows/meaningfully-${{ steps.get-version.outputs.version }}-setup.exe | |
./artifacts/windows/meaningfully-${{ steps.get-version.outputs.version }}-setup.exe.blockmap |