linux-arm-legacy-docker workflow (electerm/electerm)
The linux-arm-legacy-docker workflow from electerm/electerm, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the linux-arm-legacy-docker workflow from the electerm/electerm repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
# Simplified workflow using custom electerm-builder Docker image
name: linux-arm-legacy-docker
on:
push:
branches: [ build, test, build-only, linux-arm-legacy, legacy-build ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-24.04-arm
container: zxdong262/electerm-builder-legacy:latest # This will be our custom image
environment: build
if: ${{ !contains(github.event.head_commit.message, '[skip build]') && !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip legacy]') && !contains(github.event.head_commit.message, '[skip linux-arm-legacy]') }}
steps:
- name: Clone repository to /tmp and setup
run: |
cd /tmp
git clone https://github.com/electerm/electerm.git electerm_build
cd electerm_build
git checkout ${{ github.sha }}
# Configure npm to use /tmp for cache and global packages
mkdir -p /tmp/.npm /tmp/.npm-global
npm config set cache /tmp/.npm
npm config set prefix /tmp/.npm-global
export PATH="/tmp/.npm-global/bin:$PATH"
echo "PATH=/tmp/.npm-global/bin:$PATH" >> $GITHUB_ENV
echo "npm_config_cache=/tmp/.npm" >> $GITHUB_ENV
echo "npm_config_prefix=/tmp/.npm-global" >> $GITHUB_ENV
- name: Verify pre-installed versions
working-directory: /tmp/electerm_build
run: |
echo "=== Pre-installed versions ==="
node --version
npm --version
yarn --version
python3 --version
python --version
gcc --version
g++ --version
fpm --version
- name: Clear electron-builder cache
working-directory: /tmp/electerm_build
run: rm -rf ~/.cache/electron-builder
- name: ci init
working-directory: /tmp/electerm_build
run: npm config set legacy-peer-deps true
- name: Update electron version and remove package-lock
working-directory: /tmp/electerm_build
run: |
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json'));
pkg.devDependencies.electron = '22.3.27';
pkg.devDependencies['electron-builder'] = '26.0.20';
pkg.devDependencies['@electron/rebuild'] = '3.7.2';
pkg.dependencies['node-pty'] = '0.10.1';
pkg.dependencies.serialport = '10.5.0';
pkg.devDependencies.vite = '4';
pkg.devDependencies['@vitejs/plugin-react'] = '4.7.0';
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
"
rm -f package-lock.json
- name: Install npm dependencies
working-directory: /tmp/electerm_build
run: npm i && npm i -S @electron/rebuild@3.7.2
- name: Install R2 dependencies if needed
working-directory: /tmp/electerm_build
if: ${{ contains(github.event.head_commit.message, '[r2]') }}
run: npm i -D @aws-sdk/client-s3
- name: Build application
working-directory: /tmp/electerm_build
run: npm run b
- name: Run pb
working-directory: /tmp/electerm_build
run: npm run pb
- name: Build legacy packages
working-directory: /tmp/electerm_build
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_NUMBER: ${{ secrets.BUILD_NUMBER }}
USE_SYSTEM_FPM: true
WORKFLOW_NAME: ${{ github.workflow }}
CF_R2_ACCOUNT_ID: ${{ secrets.CF_R2_ACCOUNT_ID }}
CF_R2_BUCKET: ${{ secrets.CF_R2_BUCKET }}
CF_R2_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
CF_R2_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }}
run: node build/bin/build-linux-arm-legacy
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
# Simplified workflow using custom electerm-builder Docker image name: linux-arm-legacy-docker on: push: branches: [ build, test, build-only, linux-arm-legacy, legacy-build ] workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: timeout-minutes: 30 runs-on: latchkey-small-arm container: zxdong262/electerm-builder-legacy:latest # This will be our custom image environment: build if: ${{ !contains(github.event.head_commit.message, '[skip build]') && !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip legacy]') && !contains(github.event.head_commit.message, '[skip linux-arm-legacy]') }} steps: - name: Clone repository to /tmp and setup run: | cd /tmp git clone https://github.com/electerm/electerm.git electerm_build cd electerm_build git checkout ${{ github.sha }} # Configure npm to use /tmp for cache and global packages mkdir -p /tmp/.npm /tmp/.npm-global npm config set cache /tmp/.npm npm config set prefix /tmp/.npm-global export PATH="/tmp/.npm-global/bin:$PATH" echo "PATH=/tmp/.npm-global/bin:$PATH" >> $GITHUB_ENV echo "npm_config_cache=/tmp/.npm" >> $GITHUB_ENV echo "npm_config_prefix=/tmp/.npm-global" >> $GITHUB_ENV - name: Verify pre-installed versions working-directory: /tmp/electerm_build run: | echo "=== Pre-installed versions ===" node --version npm --version yarn --version python3 --version python --version gcc --version g++ --version fpm --version - name: Clear electron-builder cache working-directory: /tmp/electerm_build run: rm -rf ~/.cache/electron-builder - name: ci init working-directory: /tmp/electerm_build run: npm config set legacy-peer-deps true - name: Update electron version and remove package-lock working-directory: /tmp/electerm_build run: | node -e " const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('package.json')); pkg.devDependencies.electron = '22.3.27'; pkg.devDependencies['electron-builder'] = '26.0.20'; pkg.devDependencies['@electron/rebuild'] = '3.7.2'; pkg.dependencies['node-pty'] = '0.10.1'; pkg.dependencies.serialport = '10.5.0'; pkg.devDependencies.vite = '4'; pkg.devDependencies['@vitejs/plugin-react'] = '4.7.0'; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2)); " rm -f package-lock.json - name: Install npm dependencies working-directory: /tmp/electerm_build run: npm i && npm i -S @electron/rebuild@3.7.2 - name: Install R2 dependencies if needed working-directory: /tmp/electerm_build if: ${{ contains(github.event.head_commit.message, '[r2]') }} run: npm i -D @aws-sdk/client-s3 - name: Build application working-directory: /tmp/electerm_build run: npm run b - name: Run pb working-directory: /tmp/electerm_build run: npm run pb - name: Build legacy packages working-directory: /tmp/electerm_build env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_NUMBER: ${{ secrets.BUILD_NUMBER }} USE_SYSTEM_FPM: true WORKFLOW_NAME: ${{ github.workflow }} CF_R2_ACCOUNT_ID: ${{ secrets.CF_R2_ACCOUNT_ID }} CF_R2_BUCKET: ${{ secrets.CF_R2_BUCKET }} CF_R2_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }} CF_R2_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }} run: node build/bin/build-linux-arm-legacy
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.