1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 04:36:48 +00:00

ci: replace super-linter with ruff

Super-linter ran from the unpinned :latest image and, because of
branches-ignore: [master], never on pull requests to master. Ruff now
checks syntax errors and pyflakes rules (E9, F) on every push and PR.

Fixes the existing findings: unused imports and variables, an unused
duplicate import in instances/tests.py, and the star import in
accounts/views.py. settings-dev.py keeps its star import of the base
settings.
This commit is contained in:
catborise 2026-10-03 12:26:00 +03:00
parent a8725ee325
commit b04f656d2b
31 changed files with 37 additions and 114 deletions

View file

@ -1,92 +1,27 @@
########################### name: Lint
###########################
## Linter GitHub Actions ##
###########################
###########################
name: Lint Code Base
#
# Documentation:
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
#
#############################
# Start the job on all push #
#############################
on: on:
push: push:
branches: [master] branches: [master]
pull_request: pull_request:
branches-ignore: [master] branches: [master]
###############
# Set the Job #
###############
jobs: jobs:
build: ruff:
name: Lint Code Base name: Ruff
# Set the agent to run on
runs-on: ubuntu-latest runs-on: ubuntu-latest
##################
# Load all steps #
###################
steps: steps:
########################## - name: Checkout Code
# Checkout the code base # uses: actions/checkout@v4
##########################
- name: Checkout Code
uses: actions/checkout@v4
with:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: '3.12' python-version: '3.12'
- name: Install Required packages # Same ruff version as dev/requirements.txt
run: | - name: Install Ruff
sudo apt-get update -qq run: pip install "$(grep '^ruff==' dev/requirements.txt)"
sudo apt-get install -y python3-venv python3-virtualenv libvirt-dev libldap2-dev libsasl2-dev python3-lxml zlib1g-dev libxslt1-dev pkg-config gcc libssl-dev
- name: Create & Activate VENV
run: |
python3 -m venv venv
echo "$GITHUB_WORKSPACE/venv/bin" >> "$GITHUB_PATH"
- name: Install dependencies
run: |
pip3 install --upgrade pip setuptools wheel
if [ -f dev/requirements.txt ]; then pip3 install -r dev/requirements.txt; else pip3 install -r conf/requirements.txt; fi
################################
# Run Linter against code base #
################################
- name: Lint Code Base
uses: docker://github/super-linter:latest
env:
FILTER_REGEX_EXCLUDE: .*(static|scss|venv|locale|templates)/.*
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_ALL_CODEBASE: false
VALIDATE_MARKDOWN: false
VALIDATE_HTML: false
VALIDATE_JSCPD: false
VALIDATE_ANSIBLE: false
VALIDATE_CLOJURE: false
VALIDATE_COFFEE: false
VALIDATE_DART: false
VALIDATE_GO: false
VALIDATE_JSX: false
VALIDATE_KOTLIN: false
VALIDATE_POWERSHELL: false
VALIDATE_PERL: false
VALIDATE_PHP: false
VALIDATE_RAKU: false
VALIDATE_RUBY: false
VALIDATE_TSX: false
VALIDATE_TERRAFORM: false
- name: Run Ruff
run: ruff check --output-format=github .

View file

@ -1,6 +1,5 @@
import base64 import base64
import struct import struct
from unittest.mock import patch
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core import mail from django.core import mail

View file

@ -20,7 +20,7 @@ from accounts.apps import admin_password_path
from instances.models import Instance from instances.models import Instance
from accounts.forms import EmailOTPForm, ProfileForm, UserSSHKeyForm from accounts.forms import EmailOTPForm, ProfileForm, UserSSHKeyForm
from accounts.models import * from accounts.models import User, UserAttributes, UserInstance, UserSSHKey
from . import forms from . import forms
from .utils import get_user_totp_device, send_email_with_otp from .utils import get_user_totp_device, send_email_with_otp

View file

@ -1,4 +1,4 @@
from django.db import models, migrations from django.db import migrations
def apply_migration(apps, schema_editor): def apply_migration(apps, schema_editor):
Group = apps.get_model('auth', 'Group') Group = apps.get_model('auth', 'Group')

View file

@ -1,4 +1,4 @@
from .settings import app_settings, get_settings from .settings import get_settings
class AppSettingsMiddleware(object): class AppSettingsMiddleware(object):

View file

@ -1,7 +1,6 @@
# Generated by Django 3.2.13 on 2022-06-30 07:17 # Generated by Django 3.2.13 on 2022-06-30 07:17
from django.db import migrations from django.db import migrations
from django.utils.translation import gettext_lazy as _
def update_default_settings(apps, schema_editor): def update_default_settings(apps, schema_editor):
setting = apps.get_model("appsettings", "AppSettings") setting = apps.get_model("appsettings", "AppSettings")

View file

@ -1,4 +1,4 @@
from django.test import Client, TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from appsettings.models import AppSettings from appsettings.models import AppSettings

View file

@ -1,3 +1,2 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -3,7 +3,6 @@ import os
import sass import sass
from admin.decorators import superuser_only from admin.decorators import superuser_only
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
from django.utils.translation import gettext_noop as _ from django.utils.translation import gettext_noop as _

View file

@ -8,10 +8,6 @@ from django.utils import timezone
from instances.models import Instance from instances.models import Instance
from libvirt import libvirtError from libvirt import libvirtError
from vrtManager.connection import ( from vrtManager.connection import (
CONN_SOCKET,
CONN_SSH,
CONN_TCP,
CONN_TLS,
connection_manager, connection_manager,
wvmConnect, wvmConnect,
) )

View file

@ -1,3 +1,2 @@
from django.db import models
# Create your models here. # Create your models here.

View file

@ -1,11 +1,10 @@
import json import json
from unittest.mock import MagicMock, patch
from django.test import RequestFactory, TestCase from django.test import RequestFactory, TestCase
from django.urls import reverse from django.urls import reverse
from computes.models import Compute from computes.models import Compute
from datasource.views import get_client_ip, get_hostname_by_ip, os_index, os_metadata_json, os_userdata from datasource.views import get_client_ip, get_hostname_by_ip
class DataSourceTestCase(TestCase): class DataSourceTestCase(TestCase):

View file

@ -1,3 +1,2 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -290,7 +290,7 @@ class CreateInstanceViewSet(viewsets.ViewSet):
volume_list.append(volume) volume_list.append(volume)
with utils.libvirt_compute_lock(compute): with utils.libvirt_compute_lock(compute):
ret = conn.create_instance( conn.create_instance(
name=serializer.validated_data["name"], name=serializer.validated_data["name"],
memory=serializer.validated_data["memory"], memory=serializer.validated_data["memory"],
vcpu=serializer.validated_data["vcpu"], vcpu=serializer.validated_data["vcpu"],

View file

@ -4,7 +4,7 @@ disk and media mutation views must be superuser-only (matching the UI, where
the Disk tab is only rendered for superusers), and even for superusers the the Disk tab is only rendered for superusers), and even for superusers the
views must not act on volumes or option values taken blindly from the client. views must not act on volumes or option values taken blindly from the client.
""" """
from unittest.mock import MagicMock, patch from unittest.mock import patch
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.test import TestCase from django.test import TestCase

View file

@ -271,7 +271,7 @@ class InstanceSecurityMutationsTestCase(TestCase):
with patch("instances.utils.connection_manager.host_is_up", return_value=True), \ with patch("instances.utils.connection_manager.host_is_up", return_value=True), \
patch("instances.utils.wvmInstances") as mock_instances_cls, \ patch("instances.utils.wvmInstances") as mock_instances_cls, \
patch("instances.utils.wvmInstance") as mock_instance_cls, \ patch("instances.utils.wvmInstance"), \
patch("instances.utils.transaction.atomic"), \ patch("instances.utils.transaction.atomic"), \
patch("instances.utils.Instance") as mock_instance_model: patch("instances.utils.Instance") as mock_instance_model:

View file

@ -10,7 +10,6 @@ from django.contrib.auth.models import Permission
from django.http.response import Http404 from django.http.response import Http404
from django.shortcuts import reverse from django.shortcuts import reverse
from django.test import TestCase from django.test import TestCase
from instances.views import instance
from libvirt import VIR_DOMAIN_UNDEFINE_NVRAM from libvirt import VIR_DOMAIN_UNDEFINE_NVRAM
from vrtManager.create import wvmCreate from vrtManager.create import wvmCreate
from vrtManager.util import randomUUID from vrtManager.util import randomUUID

View file

@ -1,7 +1,7 @@
from admin.permissions import IsSuperUser from admin.permissions import IsSuperUser
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from computes.models import Compute from computes.models import Compute
from rest_framework import status, viewsets from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
from vrtManager.interface import wvmInterfaces, wvmInterface from vrtManager.interface import wvmInterfaces, wvmInterface

View file

@ -1,3 +1,2 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -1,3 +1,2 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -1,3 +1,2 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -1,3 +1,2 @@
from django.db import models
# Create your models here. # Create your models here.

11
pyproject.toml Normal file
View file

@ -0,0 +1,11 @@
[tool.ruff]
target-version = "py310"
extend-exclude = ["static"]
[tool.ruff.lint]
# Syntax errors and pyflakes; widen the rule set step by step.
select = ["E9", "F"]
[tool.ruff.lint.per-file-ignores]
# Settings overlay: re-exports the base settings by design.
"webvirtcloud/settings-dev.py" = ["F403", "F405"]

View file

@ -3,7 +3,7 @@ from appsettings.settings import app_settings
from computes.models import Compute from computes.models import Compute
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from drf_spectacular.utils import extend_schema, inline_serializer from drf_spectacular.utils import extend_schema, inline_serializer
from rest_framework import serializers, status, viewsets from rest_framework import serializers, viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from vrtManager.storage import wvmStorage, wvmStorages from vrtManager.storage import wvmStorage, wvmStorages

View file

@ -290,8 +290,6 @@ def create_volume(request, compute_id, pool):
compute.hostname, compute.login, compute.password, compute.type, pool compute.hostname, compute.login, compute.password, compute.type, pool
) )
storages = conn.get_storages()
form = CreateVolumeForm(request.POST or None) form = CreateVolumeForm(request.POST or None)
if form.is_valid(): if form.is_valid():
data = form.cleaned_data data = form.cleaned_data

View file

@ -1,3 +1,2 @@
from django.db import models
# Create your models here. # Create your models here.

View file

@ -1,3 +1,2 @@
from django.test import TestCase
# Create your tests here. # Create your tests here.

View file

@ -128,7 +128,6 @@ class TestReadWriteLock(unittest.TestCase):
def test_writer_blocks_subsequent_readers(self): def test_writer_blocks_subsequent_readers(self):
"""Pending writers take priority and should block subsequent new readers.""" """Pending writers take priority and should block subsequent new readers."""
order = [] order = []
lock_held_event = threading.Event()
writer_ready_event = threading.Event() writer_ready_event = threading.Event()
# Step 1: Initial reader holds read lock # Step 1: Initial reader holds read lock

View file

@ -1,4 +1,3 @@
import re
import unittest import unittest
from django.conf import settings from django.conf import settings

View file

@ -290,7 +290,6 @@ class TestPersistentDiskEditing(unittest.TestCase):
) )
def test_running_bus_change_preserves_disk_and_pending_domain_configuration(self): def test_running_bus_change_preserves_disk_and_pending_domain_configuration(self):
from lxml import etree
self.assertTrue(self.domain.isActive()) self.assertTrue(self.domain.isActive())
live_before = self.domain.XMLDesc(0) live_before = self.domain.XMLDesc(0)
self.edit(bus="sata") self.edit(bus="sata")

View file

@ -6,7 +6,7 @@ import string
import libvirt import libvirt
import lxml.etree as etree import lxml.etree as etree
from django.conf import UserSettingsHolder, settings from django.conf import settings
def is_kvm_available(xml): def is_kvm_available(xml):