Skip to content

Build for Windows

Build for Windows #488

Workflow file for this run

name: Build for Windows
on:
push:
branches:
- main
# PR branches that alter the build process should be prefixed with `build/`, so
# that this workflow runs.
- 'build/**'
schedule:
# Run this workflow every 8 hours to repackage the pre-built Drupal CMS site
# with the latest dependencies.
- cron: 0 */8 * * *
workflow_dispatch:
# Since only the x64 architecture is supported on Windows, there's only one job to
# compile PHP and build the launcher.
jobs:
app:
name: App
runs-on: windows-latest
env:
# The extensions and libraries needed to build PHP. These need to be variables so we can
# use them to generate a cache key.
# @see https://static-php.dev/en/guide/cli-generator.html
PHP_EXTENSIONS: bz2,ctype,curl,dom,filter,gd,iconv,mbstring,opcache,openssl,pdo,pdo_sqlite,phar,session,simplexml,sqlite3,tokenizer,xml,xmlwriter,yaml,zip,zlib
PHP_VERSION: 8.3
# Don't publish by default. This is overridden for the release branch, below.
PUBLISH: never
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check out latest tag
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' }}
run: |
$LATEST_TAG = git describe --tags --abbrev=0
git checkout $LATEST_TAG
"LATEST_TAG=$LATEST_TAG" >> $env:GITHUB_ENV
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
# Install PHP with the tools needed to build the interpreter, if necessary.
php-version: latest
# Composer 2.9.x is currently broken on Windows, so stick to 2.8.x for now.
# @see https://github.com/drupal/cms-launcher/actions/runs/19337936548/job/55318143930#step:12:44
tools: pecl, composer:2.8
extensions: curl, openssl, mbstring, tokenizer
ini-values: memory_limit=-1
# Cache the built binary so we can skip the build steps if there is a cache hit.
- name: Generate cache key
shell: bash
run: |
CACHE_KEY=${{ runner.os }}-$PHP_VERSION-$(echo $PHP_EXTENSIONS | tr ',' '-')
echo "CACHE_KEY=${CACHE_KEY}" >> "$GITHUB_ENV"
- id: cache-php
name: Cache PHP interpreter
uses: actions/cache@v4
with:
path: build/buildroot/bin
key: php-${{ env.CACHE_KEY }}
- if: steps.cache-php.outputs.cache-hit != 'true'
name: Install dependencies and build PHP
run: |
composer install
composer exec spc -- doctor
composer exec spc -- download --with-php=${{ env.PHP_VERSION }} --for-extensions=${{ env.PHP_EXTENSIONS }} --prefer-pre-built
composer exec spc -- build ${{ env.PHP_EXTENSIONS }} --build-cli --with-libs=freetype,libavif,libjpeg,libwebp --debug
env:
# Allows static-php-cli to download its many dependencies more smoothly.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
working-directory: build
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: latest
- name: Cache dependencies
id: cache
uses: actions/cache@v4
with:
path: node_modules
key: npm-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: npm install
- name: Build app
run: |
composer run assets --working-dir=build
Remove-Item -Recurse -Force ./bin/php.exe
Copy-Item -Force ./build/buildroot/bin/php.exe ./bin
npx electron-vite build
# If we're on a PR branch, we don't want Electron Builder to publish the app.
# On Windows, adding environment variables in PowerShell has a special syntax: see https://github.com/orgs/community/discussions/25713
- name: Prepare to publish
if: github.ref_name == 'main'
run: |
# Configure Electron Builder to publish.
"PUBLISH=onTagOrDraft" >> $env:GITHUB_ENV
# Electron Builder needs a token to publish releases.
"GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $env:GITHUB_ENV
# Pre-build the Drupal site.
npx electron . --root=drupal --no-server
Get-ChildItem -Path drupal -Recurse -Directory -Name tests | ForEach-Object { Remove-Item "drupal\$_" -Recurse -Force }
tar -c -z -f prebuilt.tar.gz --directory=drupal .
Remove-Item -Path drupal -Recurse -Force
- name: Make application
run: npx electron-builder --publish=${{ env.PUBLISH }}
env:
# Set environment variables for Azure Trusted Signing. Electron Builder will
# handle that for us automatically.
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
# For manual testing, upload the final artifact if we're not in a release branch.
- name: Upload distributable
if: ${{ env.PUBLISH == 'never' }}
uses: actions/upload-artifact@v4
with:
name: app
path: dist/*.exe
retention-days: 7
- name: Update prebuilt Drupal code base
if: ${{ env.LATEST_TAG }}
uses: softprops/action-gh-release@v2
with:
files: |
dist/Drupal_CMS-Windows.exe
dist/Drupal_CMS-Windows.exe.blockmap
dist/latest.yml
tag_name: ${{ env.LATEST_TAG }}