Skip to content

Fetch and build layout #3

Fetch and build layout

Fetch and build layout #3

name: Fetch and build layout
on:
workflow_dispatch:
inputs:
layout_id:
description: "Layout id available in URL https://configure.zsa.io/voyager/layouts/[ID_IS_HERE]/latest"
required: true
default: "emVdK"
layout_geometry:
description: "Keyboard type"
type: choice
options:
- voyager
- moonlander/reva
- moonlander/revb
- ergodox_ez
- ergodox_ez/m32u4/glow
- ergodox_ez/m32u4/shine
- ergodox_ez/stm32
- ergodox_ez/stm32/glow
- ergodox_ez/stm32/shine
- planck_ez
- planck_ez/glow
default: voyager
permissions:
contents: write
jobs:
fetch-and-build-layout:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v5
with:
ref: oryx
- name: Download the full history for the merge to work correctly
run: git pull --unshallow
- name: Download layout source
id: download-layout-source
run: |
response=$(curl --location 'https://oryx.zsa.io/graphql' \
--header 'Content-Type: application/json' \
--data '{"query":"query getLayout($hashId: String!, $revisionId: String!, $geometry: String) {layout(hashId: $hashId, geometry: $geometry, revisionId: $revisionId) { revision { hashId, qmkVersion, title }}}","variables":{"hashId":"${{ github.event.inputs.layout_id }}","geometry":"${{ github.event.inputs.layout_geometry }}","revisionId":"latest"}}' \
| jq '.data.layout.revision | [.hashId, .qmkVersion, .title]')
hash_id=$(echo "${response}" | jq -r '.[0]')
firmware_version=$(printf "%.0f" $(echo "${response}" | jq -r '.[1]'))
change_description=$(echo "${response}" | jq -r '.[2]')
if [[ -z "${change_description}" ]]; then
change_description="latest layout modification made with Oryx"
fi
curl -L "https://oryx.zsa.io/source/${hash_id}" -o source.zip
echo firmware_version=${firmware_version} >> "$GITHUB_OUTPUT"
echo change_description=${change_description} >> "$GITHUB_OUTPUT"
- name: Unzip the source file
run: |
unzip -oj source.zip '*_source/*' -d ${{ github.event.inputs.layout_id }}
rm source.zip
- name: Commit and Push changes
env:
CHANGE_DESCRIPTION: ${{ steps.download-layout-source.outputs.change_description }}
run: |
git config --local user.name "github-actions"
git config --local user.email "github-actions@github.com"
git add .
printf "✨(oryx): %s\n" "$CHANGE_DESCRIPTION" | git commit -F - || echo "No layout change"
git push
- name: Merge Oryx with custom QMK
run: |
git fetch origin main
git checkout -B main origin/main
git merge -Xignore-all-space oryx
git push
- name: Update QMK firmware submodule to latest version (${{ steps.download-layout-source.outputs.firmware_version }})
run: |
git submodule update --init --remote --depth=1 --no-single-branch
cd qmk_firmware
git checkout -B firmware${{ steps.download-layout-source.outputs.firmware_version }} \
origin/firmware${{ steps.download-layout-source.outputs.firmware_version }}
git submodule update --init --recursive
cd ..
git add qmk_firmware
git commit -m "✨(qmk): Update firmware" || echo "No QMK change"
git push
- name: Install QMK-OpenRGB module
run: |
rm -rf qmk_firmware/modules/openrgb
git clone \
--depth 1 \
--branch module_revD \
https://gitlab.com/OpenRGBDevelopers/QMK-OpenRGB.git \
qmk_firmware/modules/openrgb
# Temporary smoke-test patch:
#
# Both ZSA's Oryx module and QMK-OpenRGB implement QMK's
# raw_hid_receive() callback. That produces a duplicate-symbol
# linker error.
#
# For this test build we rename the Oryx callback so OpenRGB owns
# Raw HID exclusively. Normal keyboard functionality remains, but
# Keymapp/Kontroll host communication will not work while this
# firmware is flashed.
- name: Give Raw HID to OpenRGB for smoke test
run: |
python3 - <<'PY'
from pathlib import Path
path = Path("qmk_firmware/modules/zsa/oryx/oryx.c")
source = path.read_text()
old = "void raw_hid_receive(uint8_t *data, uint8_t length) {"
new = "void oryx_raw_hid_receive(uint8_t *data, uint8_t length) {"
count = source.count(old)
if count != 1:
raise SystemExit(
f"Expected exactly one Oryx raw_hid_receive definition, found {count}"
)
path.write_text(source.replace(old, new, 1))
PY
- name: Build qmk docker image
run: docker build -t qmk .
- name: Build the layout
id: build-layout
run: |
# Set keyboard directory and make prefix based on firmware version
if [ "${{ steps.download-layout-source.outputs.firmware_version }}" -ge 24 ]; then
keyboard_directory="qmk_firmware/keyboards/zsa"
make_prefix="zsa/"
else
keyboard_directory="qmk_firmware/keyboards"
make_prefix=""
fi
# Copy layout files to the qmk folder
rm -rf ${keyboard_directory}/${{ github.event.inputs.layout_geometry }}/keymaps/${{ github.event.inputs.layout_id }}
mkdir -p ${keyboard_directory}/${{ github.event.inputs.layout_geometry }}/keymaps
cp -r ${{ github.event.inputs.layout_id }} \
${keyboard_directory}/${{ github.event.inputs.layout_geometry }}/keymaps/
# Build the layout
docker run \
-v ./qmk_firmware:/root \
--rm \
qmk \
/bin/sh -c "
qmk setup zsa/qmk_firmware \
-b firmware${{ steps.download-layout-source.outputs.firmware_version }} \
-y
make ${make_prefix}${{ github.event.inputs.layout_geometry }}:${{ github.event.inputs.layout_id }}
"
# Find and export built layout
normalized_layout_geometry="$(echo "${{ github.event.inputs.layout_geometry }}" | sed 's/\//_/g')"
echo built_layout_file=$(find ./qmk_firmware \
-maxdepth 1 \
-type f \
-regex ".*${normalized_layout_geometry}.*\.\(bin\|hex\)$") >> "$GITHUB_OUTPUT"
echo normalized_layout_geometry=${normalized_layout_geometry} >> "$GITHUB_OUTPUT"
- name: Upload layout
uses: actions/upload-artifact@v7
with:
name: ${{ steps.build-layout.outputs.normalized_layout_geometry }}_${{ github.event.inputs.layout_id }}
path: ${{ steps.build-layout.outputs.built_layout_file }}