diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b38df29 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/dependency_review.yml b/.github/dependency_review.yml new file mode 100644 index 0000000..dfec285 --- /dev/null +++ b/.github/dependency_review.yml @@ -0,0 +1,23 @@ +fail-on-severity: 'low' +allow-licenses: + - 'BSD-2-Clause' + - 'BSD-3-Clause' + - 'BSD-3-Clause-Clear' + - 'BSD-2-Clause-Views' + - 'MIT' + - 'Apache-2.0' + - 'ISC' + - 'BlueOak-1.0.0' + - '0BSD' + - 'Python-2.0' + - 'LGPL-3.0' + - 'MPL-2.0' +fail-on-scopes: + - 'runtime' + - 'development' + - 'unknown' +license-check: true +vulnerability-check: true +allow-dependencies-licenses: + - 'pkg:pypi/PyGithub@2.2.0' + - 'pkg:pypi/psycopg2-binary' \ No newline at end of file diff --git a/.github/workflows/build_upload_whl.yml b/.github/workflows/build_upload_whl.yml deleted file mode 100644 index 38fec87..0000000 --- a/.github/workflows/build_upload_whl.yml +++ /dev/null @@ -1,205 +0,0 @@ -name: CI Build Reusable Workflow -on: - workflow_call: - secrets: - GH_TOKEN: - description: 'GitHub token for authentication' - required: true - PYPI_TOKEN: - description: 'PyPI API token to publish package' - required: false - inputs: - UPLOAD_PACKAGE: - description: 'Should the package be uploaded to PyPI?' - required: false - default: false - type: boolean - REPOSITORY_NAME: - description: 'Repository name' - required: false - type: string - BRANCH_NAME: - description: 'Branch name to checkout' - required: true - type: string - PYTHON_VERSION: - description: 'Python version to use' - required: false - default: '3.10.11' - type: string - PUSH_TAG: - description: 'Push tag after version bump' - required: false - default: false - type: boolean - RELEASE_BUILD: - description: 'Is release build?' - required: false - default: false - type: boolean - GIT_USER: - description: 'Git user name for commit and tag' - required: true - type: string - GIT_EMAIL: - description: 'Git user email for commit and tag' - required: true - type: string - PROJECT_NAME: - description: 'Project name for tests' - required: true - type: string - SOURCE_PATH: - description: 'Path to the source code directory' - required: false - default: 'src' - type: string - RUNS_ON: - description: 'Runner type for the job' - required: false - default: 'ubuntu-latest' - type: string - -jobs: - build_whl: - permissions: - contents: write - id-token: write - environment: - name: "pypi" - url: https://pypi.org/p/${{ inputs.PROJECT_NAME }} - runs-on: ${{ inputs.RUNS_ON }} - steps: - - uses: actions/checkout@v4 - with: - fetch-tags: true - fetch-depth: 0 - path: ${{ inputs.SOURCE_PATH }} - ref: ${{ inputs.BRANCH_NAME }} - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.PYTHON_VERSION }} - cache: 'pip' - - - name: Version bumping - id: VERSION_BUMP - if: inputs.RELEASE_BUILD == true - env: - GIT_AUTHOR_NAME: ${{ inputs.GIT_USER }} - GIT_AUTHOR_EMAIL: ${{ inputs.GIT_EMAIL }} - GIT_COMMITTER_NAME: ${{ inputs.GIT_USER }} - GIT_COMMITTER_EMAIL: ${{ inputs.GIT_EMAIL }} - shell: bash - run: | - python -m pip install --upgrade pip - python -m venv bump_version - source bump_version/bin/activate - pip install python-semantic-release~=10.2 - pip install -r ${{ inputs.SOURCE_PATH }}/requirements-dev.txt - mfd-create-config-files --project-dir ./${{ inputs.SOURCE_PATH }} - cd ${{ inputs.SOURCE_PATH }} - version_after_bump=$(semantic-release version --print | tail -n 1 | tr -d '\n') - version_from_tag=$(git describe --tags --abbrev=0 | tr -d '\n' | sed 's/^v//') - echo "Version after semantic-release bump is: ${version_after_bump}" - echo "Version from tag: ${version_from_tag}" - # Only check version equality if RELEASE_BUILD is true - if [ "${{ inputs.RELEASE_BUILD }}" == "true" ]; then - if [ "$version_after_bump" == "$version_from_tag" ]; then - echo "Version would not change: version_after_bump=${version_after_bump}, version_from_tag=${version_from_tag}" - exit 1 - fi - fi - semantic-release version --no-push --no-vcs-release - cat pyproject.toml - echo "version_after_bump=v${version_after_bump}" >> $GITHUB_OUTPUT - - name: Create virtual environment for whl creation - shell: bash - run: | - python -m venv whl_creation - source whl_creation/bin/activate - pip install build==1.2.2.post1 - cd ${{ inputs.SOURCE_PATH }} - ../whl_creation/bin/python -m build --wheel --outdir ../whl_creation/dist - ls -l ../whl_creation/dist - - - name: Determine if unit and functional tests should run - id: test_check - shell: bash - run: | - REPO_NAME=$(echo "${{ inputs.PROJECT_NAME }}") - echo "Repository name extracted: $REPO_NAME" - - UNIT_TEST_DIR="${{ inputs.SOURCE_PATH }}/tests/unit/test_$(echo "${REPO_NAME}" | tr '-' '_')" - FUNC_TEST_DIR="${{ inputs.SOURCE_PATH }}/tests/system/test_$(echo "${REPO_NAME}" | tr '-' '_')" - if [ -d "$UNIT_TEST_DIR" ]; then - echo "Unit tests directory exists: $UNIT_TEST_DIR" - echo "run_unit_tests=true" >> $GITHUB_OUTPUT - else - echo "Unit tests directory does not exist: $UNIT_TEST_DIR" - echo "run_unit_tests=false" >> $GITHUB_OUTPUT - fi - if [ -d "$FUNC_TEST_DIR" ]; then - echo "Functional tests directory exists: $FUNC_TEST_DIR" - echo "run_functional_tests=true" >> $GITHUB_OUTPUT - else - echo "Functional tests directory does not exist: $FUNC_TEST_DIR" - echo "run_functional_tests=false" >> $GITHUB_OUTPUT - fi - - - name: Install dependencies for tests - if: steps.test_check.outputs.run_unit_tests == 'true' || steps.test_check.outputs.run_functional_tests == 'true' - shell: bash - run: | - python -m venv test_env - source test_env/bin/activate - python -m pip install -r "${{ inputs.SOURCE_PATH }}/requirements.txt" -r "${{ inputs.SOURCE_PATH }}/requirements-test.txt" -r "${{ inputs.SOURCE_PATH }}/requirements-dev.txt" - - - name: Run unit tests if test directory exists - if: steps.test_check.outputs.run_unit_tests == 'true' - shell: bash - run: | - source test_env/bin/activate - mfd-unit-tests --project-dir ${{ github.workspace }}/${{ inputs.SOURCE_PATH }} - - - name: Run functional tests if test directory exists - if: steps.test_check.outputs.run_functional_tests == 'true' - shell: bash - run: | - source test_env/bin/activate - mfd-system-tests --project-dir ${{ github.workspace }}/${{ inputs.SOURCE_PATH }} - - name: Publish package distributions to PyPI - if: ${{ inputs.RELEASE_BUILD == true && inputs.UPLOAD_PACKAGE == true }} - uses: pypa/gh-action-pypi-publish@release/v1 - with: - packages-dir: 'whl_creation/dist' - password: ${{ secrets.PYPI_TOKEN }} - - - name: Publish comment how to build .whl - if: inputs.RELEASE_BUILD == false - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GH_TOKEN }} - script: | - const prNumber = context.payload.pull_request.number; - const commentBody = "We don't publish DEVs .whl.\n To build .whl, run 'pip install git+https://github.com/${{ inputs.REPOSITORY_NAME }}@${{ inputs.BRANCH_NAME }}'"; - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: commentBody - }); - - - name: Push git tag after version bump - if: ${{ inputs.RELEASE_BUILD == true && inputs.PUSH_TAG == true }} - shell: bash - env: - GIT_AUTHOR_NAME: ${{ inputs.GIT_USER }} - GIT_AUTHOR_EMAIL: ${{ inputs.GIT_EMAIL }} - GIT_COMMITTER_NAME: ${{ inputs.GIT_USER }} - GIT_COMMITTER_EMAIL: ${{ inputs.GIT_EMAIL }} - version_after_bump: ${{ steps.VERSION_BUMP.outputs.version_after_bump }} - run: | - cd ${{ inputs.SOURCE_PATH }} - git push origin "${version_after_bump}" \ No newline at end of file diff --git a/.github/workflows/check_code_standard.yml b/.github/workflows/check_code_standard.yml new file mode 100644 index 0000000..0df630c --- /dev/null +++ b/.github/workflows/check_code_standard.yml @@ -0,0 +1,17 @@ +name: Check Code Standard + +on: + pull_request: + types: [opened, synchronize] + +jobs: + run_check_standard: + strategy: + fail-fast: false + matrix: + python_version: ['3.10', '3.13'] + uses: intel/mfd/.github/workflows/check_code_standard.yml@main + with: + REPOSITORY_NAME: ${{ github.event.pull_request.head.repo.full_name }} + BRANCH_NAME: ${{ github.head_ref }} + PYTHON_VERSION: ${{ matrix.python_version }} diff --git a/.github/workflows/check_pr_format.yml b/.github/workflows/check_pr_format.yml new file mode 100644 index 0000000..ed32e34 --- /dev/null +++ b/.github/workflows/check_pr_format.yml @@ -0,0 +1,12 @@ +name: Title + Commit Validation + +on: + pull_request: + types: [opened, synchronize] + +jobs: + validate_pr_format: + uses: intel/mfd/.github/workflows/check_pr_format.yml@main + with: + REPOSITORY_NAME: ${{ github.event.pull_request.head.repo.full_name }} + BRANCH_NAME: ${{ github.head_ref }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4c43daf..357022c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,15 +1,4 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL Advanced" +name: CodeQL Advanced on: pull_request: @@ -18,81 +7,11 @@ on: branches: [ "main" ] jobs: - analyze: - name: Analyze (${{ matrix.language }}) - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners (GitHub.com only) - # Consider using larger runners or machines with greater resources for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - permissions: - # required for all workflows - security-events: write - - # required to fetch internal or private CodeQL packs - packages: read - - # only required for workflows in private repositories - actions: read - contents: read - + codeql_analysis: strategy: fail-fast: false matrix: - include: - - language: actions - build-mode: none - - language: python - build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' - # Use `c-cpp` to analyze code written in C, C++ or both - # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, - # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. - # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how - # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Add any setup steps before running the `github/codeql-action/init` action. - # This includes steps like installing compilers or runtimes (`actions/setup-node` - # or others). This is typically only required for manual builds. - # - name: Setup runtime (example) - # uses: actions/setup-example@v1 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" + language: ['actions', 'python'] + uses: intel/mfd/.github/workflows/codeql.yml@main + with: + LANGUAGE: ${{ matrix.language }} \ No newline at end of file diff --git a/.github/workflows/dependency_review.yml b/.github/workflows/dependency_review.yml new file mode 100644 index 0000000..ea04095 --- /dev/null +++ b/.github/workflows/dependency_review.yml @@ -0,0 +1,9 @@ +name: Dependency Review + +on: + pull_request: + types: [opened, synchronize] + +jobs: + dependency_review: + uses: intel/mfd/.github/workflows/dependency_review.yml@main diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..c9e2d96 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,21 @@ +name: CI Build + +on: + push: + branches: + - main + +jobs: + build_whl: + strategy: + fail-fast: false + matrix: + python_version: ['3.10', '3.13'] + uses: intel/mfd/.github/workflows/main.yml@main + secrets: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + with: + REPOSITORY_NAME: ${{ github.repository }} + BRANCH_NAME: ${{ github.ref_name }} + PYTHON_VERSION: ${{ matrix.python_version }} + PROJECT_NAME: 'mfd-kvm' diff --git a/.github/workflows/manual_release.yml b/.github/workflows/manual_release.yml index 307f09a..75100ea 100644 --- a/.github/workflows/manual_release.yml +++ b/.github/workflows/manual_release.yml @@ -1,23 +1,19 @@ -name: CI BUILD - RELEASE MODE +name: CI Build - Release Mode + on: workflow_dispatch: jobs: build_upload_whl: strategy: + fail-fast: false matrix: include: - - name: python-version-3-10 - python_version: '3.10' - push_tag: false - upload_package: false - continue-on-error: true - - name: python-version-3-13 - python_version: '3.13' - push_tag: true - upload_package: true - continue-on-error: true - uses: ./.github/workflows/build_upload_whl.yml + - python_version: '3.10' + release_steps: true + - python_version: '3.13' + release_steps: false + uses: intel/mfd/.github/workflows/manual_release.yml@main secrets: GH_TOKEN: ${{ secrets.GH_TOKEN }} PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} @@ -25,9 +21,5 @@ jobs: REPOSITORY_NAME: ${{ github.repository }} BRANCH_NAME: ${{ github.ref_name }} PYTHON_VERSION: ${{ matrix.python_version }} - PUSH_TAG: ${{ matrix.push_tag }} - RELEASE_BUILD: true - UPLOAD_PACKAGE: ${{ matrix.upload_package }} - GIT_USER: 'mfd-intel-bot' - GIT_EMAIL: 'mfd_intel_bot@intel.com' - PROJECT_NAME: 'mfd-kvm' \ No newline at end of file + PROJECT_NAME: 'mfd-kvm' + RELEASE_STEPS: ${{ matrix.release_steps }} diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 44e7b9e..13761c7 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -1,29 +1,20 @@ -name: DEV BUILD +name: Dev Build on: pull_request: types: [opened, synchronize] jobs: - build_upload_whl: + build_whl: strategy: + fail-fast: false matrix: - include: - - name: python-version-3-10 - python_version: '3.10' - push_tag: false - - name: python-version-3-13 - python_version: '3.13' - push_tag: false - uses: ./.github/workflows/build_upload_whl.yml + python_version: ['3.10', '3.13'] + uses: intel/mfd/.github/workflows/pull_request.yml@main secrets: GH_TOKEN: ${{ secrets.GH_TOKEN }} with: - REPOSITORY_NAME: ${{ github.repository }} + REPOSITORY_NAME: ${{ github.event.pull_request.head.repo.full_name }} BRANCH_NAME: ${{ github.head_ref }} PYTHON_VERSION: ${{ matrix.python_version }} - PUSH_TAG: ${{ matrix.push_tag }} - RELEASE_BUILD: false - GIT_USER: 'mfd-intel-bot' - GIT_EMAIL: 'mfd_intel_bot@intel.com' PROJECT_NAME: 'mfd-kvm' \ No newline at end of file diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 0000000..a01327b --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,21 @@ +name: Run Tests (ut + ft) + +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - main + +jobs: + run_tests: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + python_version: ['3.10', '3.13'] + uses: intel/mfd/.github/workflows/run_tests.yml@main + with: + PYTHON_VERSION: ${{ matrix.python_version }} + RUNS_ON: ${{ matrix.os }} + PROJECT_NAME: 'mfd-kvm' diff --git a/tests/unit/test_mfd_kvm/test_hypervisor.py b/tests/unit/test_mfd_kvm/test_hypervisor.py index e6c4e0e..ef17e37 100644 --- a/tests/unit/test_mfd_kvm/test_hypervisor.py +++ b/tests/unit/test_mfd_kvm/test_hypervisor.py @@ -13,7 +13,6 @@ from mfd_common_libs import log_levels from mfd_connect import RPyCConnection, LocalConnection from mfd_connect.base import ConnectionCompletedProcess -from mfd_connect.pathlib.path import CustomPath from mfd_connect.process.rpyc import RPyCProcess from mfd_typing import MACAddress, PCIAddress, OSName from netaddr import IPAddress @@ -286,8 +285,6 @@ def test_create_vm_from_xml(self, hv, mocker): mac_address="00:11:22:33:44:55", ) target_file = "/tmp/KVM_VM_0.xml" - with open(target_file, "w") as file: - file.write("") hv._conn.execute_command.return_value = ConnectionCompletedProcess( args="", stdout="", return_code=0 @@ -871,7 +868,6 @@ def test_attach_device(self, hv, mocker, state): hv.attach_device(name="VM_name", device_config="/path/to/config/file") hv.virt_tool.attach_device.assert_called_once() - def test_clone_vm_hdd_image_check_if_source_file_exists(self, hv): source_path = Path("/foo/source") dest_path = Path("/foo/destination")