CI workflow (FredrikNoren/ungit)
The CI workflow from FredrikNoren/ungit, explained and optimized by Latchkey.
CI health: C - fair
Run this on Latchkey for self-healing, caching, and up to 58% lower cost.
Grade your own workflow free or run it on Latchkey →What it does
This is the CI workflow from the FredrikNoren/ungit 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
name: CI
on: [push, pull_request]
permissions:
id-token: write # Required for npm OIDC provenance publishing
contents: write
jobs:
test:
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
strategy:
fail-fast: false
matrix:
node-version: ['20', '22', '*']
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
# linux dependencies
# https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces
- run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
if: matrix.os == 'ubuntu-latest'
- run: sudo add-apt-repository ppa:git-core/ppa -y && sudo apt-get update -q && sudo apt-get install -y git
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '*'
# macos dependencies
- run: brew reinstall git
if: matrix.os == 'macos-latest' && matrix.node-version == '*'
# windows dependencies
# https://github.community/t5/GitHub-Actions/TEMP-is-broken-on-Windows/td-p/30432
- run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV
if: matrix.os == 'windows-latest'
- run: choco upgrade git
if: matrix.os == 'windows-latest' && matrix.node-version == '*'
- run: git --version
- run: git config --global user.email "test@testy.com"
- run: git config --global user.name "Test testy"
- run: git config --global protocol.file.allow always # tests use file based submodules see #1539
- run: npm ci
- run: npm run lint
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
- run: npm run build
- run: npm test
# publish artifacts
- run: npm pack
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
- run: npm run electronpackage -- --all
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
- run: npm run electronzip
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
- name: Upload npm pack
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit
path: ungit-*.tgz
archive: false
retention-days: 7
- name: Upload ungit-darwin-arm64
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-darwin-arm64
path: dist/ungit-darwin-arm64.zip
archive: false
retention-days: 7
- name: Upload ungit-darwin-x64
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-darwin-x64
path: dist/ungit-darwin-x64.zip
archive: false
retention-days: 7
- name: Upload ungit-linux-arm64
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-linux-arm64
path: dist/ungit-linux-arm64.zip
archive: false
retention-days: 7
- name: Upload ungit-linux-armv7l
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-linux-armv7l
path: dist/ungit-linux-armv7l.zip
archive: false
retention-days: 7
- name: Upload ungit-linux-x64
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-linux-x64
path: dist/ungit-linux-x64.zip
archive: false
retention-days: 7
- name: Upload ungit-win32-arm64
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-win32-arm64
path: dist/ungit-win32-arm64.zip
archive: false
retention-days: 7
- name: Upload ungit-win32-ia32
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-win32-ia32
path: dist/ungit-win32-ia32.zip
archive: false
retention-days: 7
- name: Upload ungit-win32-x64
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
uses: actions/upload-artifact@v7
with:
name: ungit-win32-x64
path: dist/ungit-win32-x64.zip
archive: false
retention-days: 7
- name: Upgrade npm for trusted publishing
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' && github.repository == 'FredrikNoren/ungit' && github.ref == 'refs/heads/master'
run: npm install -g npm@latest
- name: npm publish
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' && github.repository == 'FredrikNoren/ungit' && github.ref == 'refs/heads/master'
uses: actions/github-script@v9
with:
script: |
const script = require('./scripts/npmpublish.js')
await script({github, context, core, exec})
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: CI on: [push, pull_request] permissions: id-token: write # Required for npm OIDC provenance publishing contents: write concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: test: timeout-minutes: 30 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name strategy: fail-fast: false matrix: node-version: ['20', '22', '*'] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} cache: 'npm' registry-url: 'https://registry.npmjs.org' # linux dependencies # https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces - run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 if: matrix.os == 'ubuntu-latest' - run: sudo add-apt-repository ppa:git-core/ppa -y && sudo apt-get update -q && sudo apt-get install -y git if: matrix.os == 'ubuntu-latest' && matrix.node-version == '*' # macos dependencies - run: brew reinstall git if: matrix.os == 'macos-latest' && matrix.node-version == '*' # windows dependencies # https://github.community/t5/GitHub-Actions/TEMP-is-broken-on-Windows/td-p/30432 - run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV if: matrix.os == 'windows-latest' - run: choco upgrade git if: matrix.os == 'windows-latest' && matrix.node-version == '*' - run: git --version - run: git config --global user.email "test@testy.com" - run: git config --global user.name "Test testy" - run: git config --global protocol.file.allow always # tests use file based submodules see #1539 - run: npm ci - run: npm run lint if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' - run: npm run build - run: npm test # publish artifacts - run: npm pack if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' - run: npm run electronpackage -- --all if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' - run: npm run electronzip if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' - name: Upload npm pack if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit path: ungit-*.tgz archive: false retention-days: 7 - name: Upload ungit-darwin-arm64 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-darwin-arm64 path: dist/ungit-darwin-arm64.zip archive: false retention-days: 7 - name: Upload ungit-darwin-x64 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-darwin-x64 path: dist/ungit-darwin-x64.zip archive: false retention-days: 7 - name: Upload ungit-linux-arm64 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-linux-arm64 path: dist/ungit-linux-arm64.zip archive: false retention-days: 7 - name: Upload ungit-linux-armv7l if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-linux-armv7l path: dist/ungit-linux-armv7l.zip archive: false retention-days: 7 - name: Upload ungit-linux-x64 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-linux-x64 path: dist/ungit-linux-x64.zip archive: false retention-days: 7 - name: Upload ungit-win32-arm64 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-win32-arm64 path: dist/ungit-win32-arm64.zip archive: false retention-days: 7 - name: Upload ungit-win32-ia32 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-win32-ia32 path: dist/ungit-win32-ia32.zip archive: false retention-days: 7 - name: Upload ungit-win32-x64 if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' uses: actions/upload-artifact@v7 with: name: ungit-win32-x64 path: dist/ungit-win32-x64.zip archive: false retention-days: 7 - name: Upgrade npm for trusted publishing if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' && github.repository == 'FredrikNoren/ungit' && github.ref == 'refs/heads/master' run: npm install -g npm@latest - name: npm publish if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20' && github.repository == 'FredrikNoren/ungit' && github.ref == 'refs/heads/master' uses: actions/github-script@v9 with: script: | const script = require('./scripts/npmpublish.js') await script({github, context, core, exec})
What changed
- 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 (9 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.