Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 62 additions & 15 deletions .github/workflows/cli_setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,29 @@ jobs:
runs-on: ubuntu-latest
container: ghcr.io/qmk/qmk_base_container

env:
QMK_HOME: ~/qmk_firmware

steps:
- uses: actions/checkout@v6

- name: Install dependencies
run: apt-get update && apt-get install -y python3-venv

- name: Run unit test
shell: bash
run: |
python3 -m venv .ci_venv
source .ci_venv/bin/activate
python3 -m pip install -r requirements.txt
python3 -m pip install -r requirements-dev.txt
pytest

- name: Run ci_tests
run: ./ci_tests -a
run: ./ci_tests

test_cli_linux_macos:
needs: test_cli_base_container

runs-on: ${{ matrix.os }}
env:
QMK_HOME: ~/qmk_firmware

strategy:
matrix:
os: [macos-latest, ubuntu-latest]
Expand All @@ -43,14 +48,12 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Run ci_tests
run: ./ci_tests -a
run: ./ci_tests

test_cli_win:
needs: test_cli_base_container

runs-on: windows-latest
env:
QMK_HOME: $HOME/qmk_firmware

steps:
- uses: actions/checkout@v6
Expand All @@ -59,19 +62,63 @@ jobs:
uses: msys2/setup-msys2@v2
with:
update: true
install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-build mingw-w64-x86_64-python-pillow mingw-w64-x86_64-rust
install: git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-build mingw-w64-x86_64-python-pillow mingw-w64-x86_64-rust mingw-w64-x86_64-python-halo mingw-w64-x86_64-python-nh3 mingw-w64-x86_64-python-rpds-py

# Upgrade pip due to msys packaging + pypa/build/pull/736 issues
- name: (MSYS2) Install Python dependencies
shell: msys2 {0}
run: |
python3 -m pip install --break-system-packages --force-reinstall --upgrade pip

- name: (MSYS2) Install QMK CLI from source
- name: Run ci_tests
shell: msys2 {0}
run: ./ci_tests

test_docker_container:
needs: test_cli_base_container

runs-on: ubuntu-latest

env:
TEST_TAG: qmkfm/qmk_cli:test

steps:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.9'

- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- uses: actions/checkout@v6

- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
pip install setuptools wheel
pip install -r requirements-dev.txt

- name: Build Python
run: |
python3 -m build
python3 -m pip install --break-system-packages dist/qmk-*.tar.gz
- name: (MSYS2) Run qmk setup -y
shell: msys2 {0}
run: qmk setup -y

- name: Build container for current runner
uses: docker/build-push-action@v7
with:
context: .
load: true
tags: ${{ env.TEST_TAG }}

- name: Test
run: |
docker run --rm ${{ env.TEST_TAG }} qmk setup -y

- name: Build actual containers
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64
42 changes: 0 additions & 42 deletions .github/workflows/docker-pr.yml

This file was deleted.

54 changes: 10 additions & 44 deletions ci_tests
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,23 @@
set -e
#set -x

ADVANCED=false
TMPDIR=$(mktemp -d)
QMK_HOME="$TMPDIR/qmk_firmware"
export QMK_HOME

for arg in $@; do
if [ "$arg" = "-a" ]; then
ADVANCED=true
fi
done

if [ $ADVANCED = true ]; then
echo "*** Running in advanced mode with tmp files in $TMPDIR"
else
echo "*** Running in basic mode with tmp files in $TMPDIR"
fi

# Setup our virtualenv
if [ -e .ci_venv ]; then
rm -rf .ci_venv
trap "rm -rf $TMPDIR" EXIT

CI_VENV="$TMPDIR/.ci_venv"

# Avoid issues with building pillow as we install mingw-w64-x86_64-python-pillow
if [[ "$(uname -s)" =~ ^MINGW64_NT.* ]]; then
CI_VENV_ARGS="--system-site-packages"
fi

python3 -m venv .ci_venv
source .ci_venv/bin/activate
python3 -m venv $CI_VENV_ARGS $CI_VENV
source $CI_VENV/bin/activate

# Install dependencies
python3 -m pip install -U pip wheel
python3 -m pip install .
python3 -m pip install -r requirements-dev.txt

# Ensure that qmk works
echo "*** Testing 'qmk clone -h'"
qmk clone -h
#echo "*** Testing 'qmk config -a'" # Test disabled as `milc` at least 1.6.8+ returns False and thus non-zero exit code
#qmk config -a
echo "*** Testing 'qmk setup -n'"
qmk setup -n

echo
echo "*** Basic tests completed successfully!"

# Run advanced test if requested
if [ $ADVANCED = true ]; then
echo
echo "*** Testing 'qmk setup -y'"
qmk setup -y

echo
echo "*** Advanced tests completed successfully!"
fi

# Cleanup
deactivate
rm -rf .ci_venv $TMPDIR
pytest -vv -m system --qmk=real
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@ requires = [
"wheel"
]
build-backend = "setuptools.build_meta"

[tool.pytest.ini_options]
markers = [
"integration",
"system",
]
addopts = "-m 'not (integration or system)'"
64 changes: 53 additions & 11 deletions qmk_cli/git.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
"""Helpers for working with git.
"""
import subprocess
import shutil

from milc import cli

default_repo = 'qmk_firmware'
default_fork = 'qmk/' + default_repo
default_branch = 'master'
DEFAULT_UPSTREAM = 'https://github.com/qmk/qmk_firmware'


def git_clone(url, destination, branch):
git_clone = [
'git',
'clone',
'--recurse-submodules',
'--branch=' + branch,
f'--branch={branch}',
url,
str(destination),
]
cli.log.debug('Git clone command: %s', git_clone)
cli.log.debug(f'Git clone command: {git_clone}')

try:
with subprocess.Popen(git_clone, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8') as p:
Expand All @@ -28,13 +27,56 @@ def git_clone(url, destination, branch):
except Exception as e:
git_cmd = ' '.join([s.replace(' ', r'\ ') for s in git_clone])

cli.log.error("Could not run '%s': %s: %s", git_cmd, e.__class__.__name__, e)
cli.log.error(f"Could not run '{git_cmd}': {e.__class__.__name__}:{e}")
return False

if p.returncode == 0:
cli.log.info('Successfully cloned %s to %s!', url, destination)
return True
if p.returncode != 0:
cli.log.error(f'git clone exited {p.returncode}')
return False

cli.log.info(f'Successfully cloned {url} to {destination}!')
return True


def git_set_upstream(destination):
"""Add the qmk/qmk_firmware upstream to a qmk_firmware clone.
"""
git_cmd = [
'git',
'-C',
destination,
'remote',
'add',
'upstream',
DEFAULT_UPSTREAM,
]

else:
cli.log.error('git clone exited %d', p.returncode)
try:
with subprocess.Popen(git_cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8') as p:
for line in p.stdout:
print(line, end='')

except Exception as e:
git_cmd = ' '.join([s.replace(' ', r'\ ') for s in git_cmd])

cli.log.error(f"Could not run '{git_cmd}': {e.__class__.__name__}:{e}")
return False

if p.returncode != 0:
cli.log.error(f'git remote add exited {p.returncode}')
return False

cli.log.info(f'Added {DEFAULT_UPSTREAM} as remote upstream.')
return True


def git_clone_fork(destination, baseurl, fork, branch, force=False):
url = '/'.join((baseurl, fork))

if force:
shutil.rmtree(destination)

if not git_clone(url, destination, branch):
return False

return git_set_upstream(destination)
2 changes: 1 addition & 1 deletion qmk_cli/subcommands/clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ def clone(cli):
# Exists (but not an empty dir)
if cli.args.destination.exists() and any(cli.args.destination.iterdir()):
cli.log.error('Destination already exists: %s', cli.args.destination)
exit(1)
return False

return git_clone(git_url, cli.args.destination, cli.args.branch)
5 changes: 5 additions & 0 deletions qmk_cli/subcommands/env.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Prints environment information.
"""
import os
import sys
from pathlib import Path

from milc import cli
Expand All @@ -26,6 +27,10 @@ def env(cli):
data[converted_key] = val

if cli.args.var:
if cli.args.var not in data:
print(f'Variable "{cli.args.var}" does not exist!', file=sys.stderr)
return False

# dump out requested arg
print(data[cli.args.var])
else:
Expand Down
Loading
Loading