Skip to content
Latchkey

Build workflow (Syncplay/syncplay)

The Build workflow from Syncplay/syncplay, explained and optimized by Latchkey.

D

CI health: D - needs work

Point runs-on at Latchkey and get caching, run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: Syncplay/syncplay.github/workflows/build.ymlLicense Apache-2.0View source

What it does

This is the Build workflow from the Syncplay/syncplay repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Build
on: [push, pull_request]

jobs:
  windows:
    name: Build for Windows
    runs-on: windows-2022
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.8'
          architecture: x86

      - name: Check Python install
        run: |
          which python
          python --version
          python -c "import struct; print(struct.calcsize('P') * 8)"
          which pip
          pip --version

      - name: Install Python dependencies
        run: |
          pip3 install -U setuptools wheel pip
          pip3 install -r requirements.txt
          pip3 install -r requirements_gui.txt
          pip3 install py2exe

      - name: Check Python dependencies
        run: |
          python3 -c "from PySide2 import __version__; print(__version__)"
          python3 -c "from PySide2.QtCore import __version__; print(__version__)"
          python3 -c "from PySide2.QtCore import QLibraryInfo; print(QLibraryInfo.location(QLibraryInfo.LibrariesPath))"

      - name: Build
        run: |
          $ver = (findstr version .\syncplay\__init__.py).split("'")[1]
          echo $ver
          echo "VER=$ver" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
          python buildPy2exe.py
          New-Item -Path syncplay_v$ver -Name "syncplay.ini" -Value " "

      - name: Prepare for deployment
        run: dir

      - name: Deploy portable
        uses: actions/upload-artifact@v4
        with:
          name: Syncplay_${{ env.VER }}_Portable
          path: |
            syncplay_v${{ env.VER }}

      - name: Deploy installer
        uses: actions/upload-artifact@v4
        with:
          name: Syncplay-${{ env.VER }}-Setup.exe
          path: |
            Syncplay-${{ env.VER }}-Setup.exe

  macos:
    name: Build for macOS
    runs-on: macos-15-intel
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Python
        run: |
          wget https://www.python.org/ftp/python/3.10.6/python-3.10.6-macos11.pkg
          sudo installer -verbose -pkg ./python-3.10.6-macos11.pkg -target /
          echo "/Library/Frameworks/Python.framework/Versions/3.10/bin" >> $GITHUB_PATH

      - name: Check Python install
        run: |
          which python3
          python3 --version
          which pip3
          pip3 --version
          file $(which python3)

      - name: Install Python dependencies
        run: |
          pip3 install -U pip setuptools==70.3.0 wheel
          pip3 install -r requirements.txt
          pip3 install -r requirements_gui.txt
          pip3 install py2app

      - name: Install universal2 dependencies
        env:
          CFLAGS: -arch x86_64 -arch arm64
          ARCHFLAGS: -arch x86_64 -arch arm64
        run: |
          pip3 uninstall zope.interface -y
          pip3 install --no-binary :all: zope.interface

          pip3 uninstall cffi -y
          pip3 install --no-binary :all: cffi

          pip3 uninstall cryptography -y
          pip3 download --platform macosx_10_10_universal2 --only-binary :all: --no-deps --dest . cryptography
          pip3 install --no-cache-dir --no-index --find-links . cryptography

          pip3 uninstall charset-normalizer -y
          pip3 download --platform macosx_10_9_universal2 --only-binary :all: --no-deps --dest . charset-normalizer
          pip3 install --no-cache-dir --no-index --find-links . charset-normalizer

      - name: Check Python dependencies
        run: |
          python3 -c "from PySide6 import __version__; print(__version__)"
          python3 -c "from PySide6.QtCore import __version__; print(__version__)"
          python3 -c "from PySide6.QtCore import QLibraryInfo; print(QLibraryInfo.path(QLibraryInfo.LibrariesPath))"
          python3 -c "import ssl; print(ssl)"
          python3 -c "from py2app.recipes import pyside6"
          python3 -c 'from distutils.sysconfig import get_config_var; print(get_config_var("LDLIBRARY"))'

      - name: Build
        run: |
          python3 buildPy2app.py py2app

      - name: Prepare for deployment
        run: |
          ls -al
          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
          echo "VER=$VER" >> $GITHUB_ENV
          mkdir dist_actions
          ci/macos-deploy.sh
          ls -al dist_actions

      - name: Deploy
        uses: actions/upload-artifact@v4
        with:
          name: Syncplay_${{ env.VER }}.dmg
          path: |
            dist_actions/Syncplay_${{ env.VER }}.dmg

  deb:
    name: Build Debian package
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Build
        run: ci/deb-script.sh

      - name: Build server
        run: ci/deb-server-script.sh

      - name: Test
        run: ci/deb-installation-test.sh

      - name: Prepare for deployment
        run: |
          ls -al
          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
          echo "VER=$VER" >> $GITHUB_ENV
          mkdir dist_actions
          mv /tmp/syncplay.deb dist_actions/syncplay_${VER}.deb
          mv /tmp/syncplay-server.deb dist_actions/syncplay-server_${VER}.deb
          ls -al dist_actions

      - name: Deploy full deb
        uses: actions/upload-artifact@v4
        with:
          name: syncplay.deb
          path: |
            dist_actions/syncplay_*.deb

      - name: Deploy server deb
        uses: actions/upload-artifact@v4
        with:
          name: syncplay-server.deb
          path: |
            dist_actions/syncplay-server_*.deb

The same workflow, on Latchkey

Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.

name: Build
on: [push, pull_request]
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  windows:
    timeout-minutes: 30
    name: Build for Windows
    runs-on: windows-2022
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          cache: 'pip'
          python-version: '3.8'
          architecture: x86
 
      - name: Check Python install
        run: |
          which python
          python --version
          python -c "import struct; print(struct.calcsize('P') * 8)"
          which pip
          pip --version
 
      - name: Install Python dependencies
        run: |
          pip3 install -U setuptools wheel pip
          pip3 install -r requirements.txt
          pip3 install -r requirements_gui.txt
          pip3 install py2exe
 
      - name: Check Python dependencies
        run: |
          python3 -c "from PySide2 import __version__; print(__version__)"
          python3 -c "from PySide2.QtCore import __version__; print(__version__)"
          python3 -c "from PySide2.QtCore import QLibraryInfo; print(QLibraryInfo.location(QLibraryInfo.LibrariesPath))"
 
      - name: Build
        run: |
          $ver = (findstr version .\syncplay\__init__.py).split("'")[1]
          echo $ver
          echo "VER=$ver" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
          python buildPy2exe.py
          New-Item -Path syncplay_v$ver -Name "syncplay.ini" -Value " "
 
      - name: Prepare for deployment
        run: dir
 
      - name: Deploy portable
        uses: actions/upload-artifact@v4
        with:
          name: Syncplay_${{ env.VER }}_Portable
          path: |
            syncplay_v${{ env.VER }}
 
      - name: Deploy installer
        uses: actions/upload-artifact@v4
        with:
          name: Syncplay-${{ env.VER }}-Setup.exe
          path: |
            Syncplay-${{ env.VER }}-Setup.exe
 
  macos:
    timeout-minutes: 30
    name: Build for macOS
    runs-on: macos-15-intel
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Setup Python
        run: |
          wget https://www.python.org/ftp/python/3.10.6/python-3.10.6-macos11.pkg
          sudo installer -verbose -pkg ./python-3.10.6-macos11.pkg -target /
          echo "/Library/Frameworks/Python.framework/Versions/3.10/bin" >> $GITHUB_PATH
 
      - name: Check Python install
        run: |
          which python3
          python3 --version
          which pip3
          pip3 --version
          file $(which python3)
 
      - name: Install Python dependencies
        run: |
          pip3 install -U pip setuptools==70.3.0 wheel
          pip3 install -r requirements.txt
          pip3 install -r requirements_gui.txt
          pip3 install py2app
 
      - name: Install universal2 dependencies
        env:
          CFLAGS: -arch x86_64 -arch arm64
          ARCHFLAGS: -arch x86_64 -arch arm64
        run: |
          pip3 uninstall zope.interface -y
          pip3 install --no-binary :all: zope.interface
 
          pip3 uninstall cffi -y
          pip3 install --no-binary :all: cffi
 
          pip3 uninstall cryptography -y
          pip3 download --platform macosx_10_10_universal2 --only-binary :all: --no-deps --dest . cryptography
          pip3 install --no-cache-dir --no-index --find-links . cryptography
 
          pip3 uninstall charset-normalizer -y
          pip3 download --platform macosx_10_9_universal2 --only-binary :all: --no-deps --dest . charset-normalizer
          pip3 install --no-cache-dir --no-index --find-links . charset-normalizer
 
      - name: Check Python dependencies
        run: |
          python3 -c "from PySide6 import __version__; print(__version__)"
          python3 -c "from PySide6.QtCore import __version__; print(__version__)"
          python3 -c "from PySide6.QtCore import QLibraryInfo; print(QLibraryInfo.path(QLibraryInfo.LibrariesPath))"
          python3 -c "import ssl; print(ssl)"
          python3 -c "from py2app.recipes import pyside6"
          python3 -c 'from distutils.sysconfig import get_config_var; print(get_config_var("LDLIBRARY"))'
 
      - name: Build
        run: |
          python3 buildPy2app.py py2app
 
      - name: Prepare for deployment
        run: |
          ls -al
          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
          echo "VER=$VER" >> $GITHUB_ENV
          mkdir dist_actions
          ci/macos-deploy.sh
          ls -al dist_actions
 
      - name: Deploy
        uses: actions/upload-artifact@v4
        with:
          name: Syncplay_${{ env.VER }}.dmg
          path: |
            dist_actions/Syncplay_${{ env.VER }}.dmg
 
  deb:
    timeout-minutes: 30
    name: Build Debian package
    runs-on: latchkey-small
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Build
        run: ci/deb-script.sh
 
      - name: Build server
        run: ci/deb-server-script.sh
 
      - name: Test
        run: ci/deb-installation-test.sh
 
      - name: Prepare for deployment
        run: |
          ls -al
          export VER="$(cat syncplay/__init__.py | awk '/version/ {gsub("\047", "", $3); print $NF}')"
          echo "VER=$VER" >> $GITHUB_ENV
          mkdir dist_actions
          mv /tmp/syncplay.deb dist_actions/syncplay_${VER}.deb
          mv /tmp/syncplay-server.deb dist_actions/syncplay-server_${VER}.deb
          ls -al dist_actions
 
      - name: Deploy full deb
        uses: actions/upload-artifact@v4
        with:
          name: syncplay.deb
          path: |
            dist_actions/syncplay_*.deb
 
      - name: Deploy server deb
        uses: actions/upload-artifact@v4
        with:
          name: syncplay-server.deb
          path: |
            dist_actions/syncplay-server_*.deb
 

What changed

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:

This workflow runs 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow