From b1a1a6866d1b82bdf9106d667ad5f794fbe835b0 Mon Sep 17 00:00:00 2001 From: Hal <13111745+loonghao@users.noreply.github.com> Date: Mon, 6 Jan 2025 01:26:03 +0800 Subject: [PATCH] Initial commit --- .coveragerc | 13 +++++ .flake8 | 34 +++++++++++++ .github/workflows/build-exe.yml | 60 +++++++++++++++++++++++ .github/workflows/bumpversion.yml | 23 +++++++++ .github/workflows/codecov.yml | 34 +++++++++++++ .github/workflows/issue-translator.yml | 18 +++++++ .github/workflows/mr-test.yml | 35 ++++++++++++++ .github/workflows/python-publish.yml | 66 ++++++++++++++++++++++++++ .gitignore | 22 +++++++++ .hound.yml | 8 ++++ .pre-commit-config.yaml | 12 +++++ .pylintrc | 7 +++ LICENSE | 21 ++++++++ README.md | 2 + codecov.yml | 9 ++++ nox_actions/__init__.py | 0 nox_actions/codetest.py | 17 +++++++ nox_actions/lint.py | 17 +++++++ nox_actions/release.py | 45 ++++++++++++++++++ nox_actions/utils.py | 19 ++++++++ noxfile.py | 24 ++++++++++ renovate.json | 6 +++ requirements-dev.txt | 3 ++ 23 files changed, 495 insertions(+) create mode 100644 .coveragerc create mode 100644 .flake8 create mode 100644 .github/workflows/build-exe.yml create mode 100644 .github/workflows/bumpversion.yml create mode 100644 .github/workflows/codecov.yml create mode 100644 .github/workflows/issue-translator.yml create mode 100644 .github/workflows/mr-test.yml create mode 100644 .github/workflows/python-publish.yml create mode 100644 .gitignore create mode 100644 .hound.yml create mode 100644 .pre-commit-config.yaml create mode 100644 .pylintrc create mode 100644 LICENSE create mode 100644 README.md create mode 100644 codecov.yml create mode 100644 nox_actions/__init__.py create mode 100644 nox_actions/codetest.py create mode 100644 nox_actions/lint.py create mode 100644 nox_actions/release.py create mode 100644 nox_actions/utils.py create mode 100644 noxfile.py create mode 100644 renovate.json create mode 100644 requirements-dev.txt diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..8cc23c9 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True +source = + +[report] +exclude_lines = + if self.debug: + pragma: no cover + raise NotImplementedError + if __name__ == .__main__.: +ignore_errors = True +omit = + tests/* diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..97fffa9 --- /dev/null +++ b/.flake8 @@ -0,0 +1,34 @@ +[flake8] +ignore = BLK100 + +# flake8-quotes: +# Use double quotes as our default to comply with black, we like it and +# don't want to use single quotes anymore. +# We would love to configure this via our pyproject.toml but flake8-3.8 does +# not support it yet. +inline-quotes = double +multiline-quotes = double +docstring-quotes = double +avoid-escape = True + +# flake8-docstrings +# Use the Google Python Styleguide Docstring format. +docstring-convention=google + +exclude = + # No need to traverse our git directory + .git, + # There's no value in checking cache directories + __pycache__, + # The conf file is mostly autogenerated, ignore it + docs/source/conf.py, + # The old directory contains Flake8 2.0 + old, + # This contains our built documentation + build, + # This contains builds of flake8 that we don't want to check + dist, + venv, + docs + +max-line-length = 120 diff --git a/.github/workflows/build-exe.yml b/.github/workflows/build-exe.yml new file mode 100644 index 0000000..67f414d --- /dev/null +++ b/.github/workflows/build-exe.yml @@ -0,0 +1,60 @@ +name: Build Executable + +on: + workflow_run: + workflows: ["Python Package"] + types: + - completed + branches: + - "main" + +jobs: + build: + # Only run if the python-publish workflow succeeded + if: ${{ github.event.workflow_run.conclusion == 'success' }} + strategy: + fail-fast: false + matrix: + target: + - os: windows-2022 + triple: x86_64-pc-windows-msvc + - os: ubuntu-22.04 + triple: x86_64-unknown-linux-gnu + - os: macos-12 + triple: x86_64-apple-darwin + runs-on: ${{ matrix.target.os }} + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: olegtarasov/get-tag@v2.1.4 + id: get_tag_name + with: + tagRegex: "v(?.*)" + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + cache: pip + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install nox + + - name: Build exe + run: | + nox -s build-exe -- --release --version ${{ steps.get_tag_name.outputs.version }} + + - uses: ncipollo/release-action@v1 + with: + allowUpdates: true + updateOnlyUnreleased: false + omitBody: true + artifacts: ".zip/*.zip" + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} diff --git a/.github/workflows/bumpversion.yml b/.github/workflows/bumpversion.yml new file mode 100644 index 0000000..9aa25f4 --- /dev/null +++ b/.github/workflows/bumpversion.yml @@ -0,0 +1,23 @@ +name: Bump version + +on: + push: + branches: + - main + +jobs: + bump-version: + if: "!startsWith(github.event.head_commit.message, 'bump:')" + runs-on: ubuntu-latest + name: "Bump version and create changelog with commitizen" + steps: + - name: Check out + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + token: '${{ secrets.PERSONAL_ACCESS_TOKEN }}' + - name: Create bump and changelog + uses: commitizen-tools/commitizen-action@master + with: + github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + branch: main diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 0000000..6103542 --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,34 @@ +name: Codecov +on: [push, pull_request] +jobs: + run: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get repository name + id: repo-name + uses: MariachiBear/get-repo-name-action@v1.3.0 + with: + with-owner: 'true' + string-case: 'uppercase' + - name: Set up Python 3.10 + uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Install dependencies + run: | + python -m pip install -r requirements-dev.txt + poetry --version + - name: Run tests and collect coverage + run: | + nox -s pytest + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + slug: loonghao/${{ steps.repo-name.outputs.repository-name }} + files: 'coverage.xml' + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/issue-translator.yml b/.github/workflows/issue-translator.yml new file mode 100644 index 0000000..83c127b --- /dev/null +++ b/.github/workflows/issue-translator.yml @@ -0,0 +1,18 @@ +name: 'issue-translator' +on: + issue_comment: + types: [created] + issues: + types: [opened] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: usthe/issues-translate-action@v2.7 + with: + IS_MODIFY_TITLE: false + # not require, default false, . Decide whether to modify the issue title + # if true, the robot account @Issues-translate-bot must have modification permissions, invite @Issues-translate-bot to your project or use your custom bot. + CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically. πŸ‘―πŸ‘­πŸ»πŸ§‘β€πŸ€β€πŸ§‘πŸ‘«πŸ§‘πŸΏβ€πŸ€β€πŸ§‘πŸ»πŸ‘©πŸΎβ€πŸ€β€πŸ‘¨πŸΏπŸ‘¬πŸΏ + # not require. Customize the translation robot prefix message. diff --git a/.github/workflows/mr-test.yml b/.github/workflows/mr-test.yml new file mode 100644 index 0000000..9d86cf0 --- /dev/null +++ b/.github/workflows/mr-test.yml @@ -0,0 +1,35 @@ +name: MR Checks +on: [ pull_request ] + +jobs: + python-check: + strategy: + max-parallel: 3 + matrix: + target: + - os: 'ubuntu-22.04' + triple: 'x86_64-unknown-linux-gnu' + - os: 'macos-12' + triple: 'x86_64-apple-darwin' + - os: 'windows-2022' + triple: 'x86_64-pc-windows-msvc' + python-version: ["3.10"] + fail-fast: false + runs-on: ${{ matrix.target.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install -r requirements-dev.txt + poetry --version + - name: lint + run: | + nox -s lint + - name: test build + run: | + nox -s build-exe -- --test diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..09e3b26 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,66 @@ +name: Upload Python Package + +on: + push: + tags: + - "v*" + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + contents: write + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + token: "${{ secrets.GITHUB_TOKEN }}" + fetch-depth: 0 + ref: main + - uses: olegtarasov/get-tag@v2.1.4 + id: get_tag_name + with: + tagRegex: "v(?.*)" + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install -r requirements-dev.txt + poetry --version + poetry build + # Note that we don't need credentials. + # We rely on https://docs.pypi.org/trusted-publishers/. + - name: Upload to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist + - name: Generate changelog + id: changelog + uses: jaywcjlove/changelog-generator@main + with: + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + filter-author: (|dependabot|renovate\\[bot\\]|dependabot\\[bot\\]|Renovate Bot) + filter: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}' + template: | + ## Bugs + {{fix}} + ## Feature + {{feat}} + ## Improve + {{refactor,perf,clean}} + ## Misc + {{chore,style,ci||πŸ”Ά Nothing change}} + ## Unknown + {{__unknown__}} + - uses: ncipollo/release-action@v1 + with: + artifacts: "dist/*" + token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + body: | + Comparing Changes: ${{ steps.changelog.outputs.compareurl }} + + ${{ steps.changelog.outputs.changelog }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fbedea2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Byte-compiled / optimized / DLL files +*.py[cod] + +# PyCharm project files +.idea/ + +# Vim / Notepad++ temp files +*~ + +# Coverage output +.coverage + +# Documentation build folders. +docs/_* +docs/src/* +target/* +/venv/ +/run_pycharm.bat +/.nox/ +/build/ +/coverage.xml +/.zip/ diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 0000000..faeeeeb --- /dev/null +++ b/.hound.yml @@ -0,0 +1,8 @@ +python: + enabled: true + +flake8: + enabled: true + config_file: .flake8 + +fail_on_violations: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..b049e1e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,12 @@ +default_language_version: + python: python3.10 +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: no-commit-to-branch # prevent direct commits to main branch + - id: check-yaml + args: ["--unsafe"] + - id: check-toml + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..c205a4e --- /dev/null +++ b/.pylintrc @@ -0,0 +1,7 @@ +# Generated Pylint configuration file that disables default output tables. + +[MESSAGES CONTROL] +disable=RP0001,RP0002,RP0003,RP0101,RP0401,RP0402,RP0701,RP0801,C0103,R0903 + +[REPORTS] +output-format=text diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8f0f47b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Hal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..feb16a7 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# repo-template +This is a boilerplate git repository for creating new project diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..b3befa7 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,9 @@ +coverage: + status: + project: off + +github_checks: + annotations: false + +ignore: + - "noxfile.py" diff --git a/nox_actions/__init__.py b/nox_actions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nox_actions/codetest.py b/nox_actions/codetest.py new file mode 100644 index 0000000..da570f3 --- /dev/null +++ b/nox_actions/codetest.py @@ -0,0 +1,17 @@ +# Import built-in modules +import os + +# Import third-party modules +import nox +from nox_actions.utils import PACKAGE_NAME +from nox_actions.utils import THIS_ROOT + + +def pytest(session: nox.Session) -> None: + session.install(".") + session.install("pytest", "pytest_cov", "pytest_mock") + test_root = os.path.join(THIS_ROOT, "tests") + session.run("pytest", f"--cov={PACKAGE_NAME}", + "--cov-report=xml:coverage.xml", + f"--rootdir={test_root}", + env={"PYTHONPATH": THIS_ROOT.as_posix()}) diff --git a/nox_actions/lint.py b/nox_actions/lint.py new file mode 100644 index 0000000..9b75bc1 --- /dev/null +++ b/nox_actions/lint.py @@ -0,0 +1,17 @@ +# Import third-party modules +import nox +from nox_actions.utils import PACKAGE_NAME + + +def lint(session: nox.Session) -> None: + session.install("isort", "ruff") + session.run("isort", "--check-only", PACKAGE_NAME) + session.run("ruff", "check") + + +def lint_fix(session: nox.Session) -> None: + session.install("isort", "ruff", "pre-commit", "autoflake") + session.run("ruff", "check", "--fix") + session.run("isort", ".") + session.run("pre-commit", "run", "--all-files") + session.run("autoflake", "--in-place", "--remove-all-unused-imports", "--remove-unused-variables") diff --git a/nox_actions/release.py b/nox_actions/release.py new file mode 100644 index 0000000..8a071a3 --- /dev/null +++ b/nox_actions/release.py @@ -0,0 +1,45 @@ +# Import built-in modules +import argparse +import os +import shutil +import zipfile + +# Import third-party modules +import nox +from nox_actions.utils import PACKAGE_NAME +from nox_actions.utils import THIS_ROOT + + +@nox.session(name="build-exe", reuse_venv=True) +def build_exe(session: nox.Session) -> None: + parser = argparse.ArgumentParser(prog="nox -s build-exe --release") + parser.add_argument("--release", action="store_true") + parser.add_argument("--version", default="0.5.0", help="Version to use for the zip file") + parser.add_argument("--test", action="store_true") + args = parser.parse_args(session.posargs) + build_root = THIS_ROOT / "build" + session.install("pyoxidizer") + session.run("pyoxidizer", "build", "install", "--path", THIS_ROOT, "--release") + for platform_name in os.listdir(build_root): + platform_dir = build_root / platform_name / "release" / "install" + print(os.listdir(platform_dir)) + print(f"build {platform_name} -> {platform_dir}") + + if args.test: + print("run tests") + vexcle_exe = shutil.which("vexcle", path=platform_dir) + assert os.path.exists(vexcle_exe) + + if args.release: + temp_dir = os.path.join(THIS_ROOT, ".zip") + version = str(args.version) + print(f"make zip to current version: {version}") + os.makedirs(temp_dir, exist_ok=True) + zip_file = os.path.join(temp_dir, f"{PACKAGE_NAME}-{version}-{platform_name}.zip") + with zipfile.ZipFile(zip_file, "w") as zip_obj: + for root, _, files in os.walk(platform_dir): + for file in files: + zip_obj.write(os.path.join(root, file), + os.path.relpath(os.path.join(root, file), + os.path.join(platform_dir, "."))) + print("Saving to {zipfile}".format(zipfile=zip_file)) diff --git a/nox_actions/utils.py b/nox_actions/utils.py new file mode 100644 index 0000000..e5d0fe3 --- /dev/null +++ b/nox_actions/utils.py @@ -0,0 +1,19 @@ +# Import built-in modules +from pathlib import Path + + +PACKAGE_NAME = "" +THIS_ROOT = Path(__file__).parent.parent +PROJECT_ROOT = THIS_ROOT.parent + + +def _assemble_env_paths(*paths): + """Assemble environment paths separated by a semicolon. + + Args: + *paths: Paths to be assembled. + + Returns: + str: Assembled paths separated by a semicolon. + """ + return ";".join(paths) diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 0000000..70752f8 --- /dev/null +++ b/noxfile.py @@ -0,0 +1,24 @@ +# Import built-in modules +import os +import sys + +# Import third-party modules +import nox + + +ROOT = os.path.dirname(__file__) + +# Ensure maya_umbrella is importable. +if ROOT not in sys.path: + sys.path.append(ROOT) + +# Import third-party modules +from nox_actions import codetest # noqa: E402 +from nox_actions import lint # noqa: E402 +from nox_actions import release # noqa: E402 + + +nox.session(lint.lint, name="lint") +nox.session(lint.lint_fix, name="lint-fix") +nox.session(codetest.pytest, name="pytest") +nox.session(release.build_exe, name="build-exe") diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..be84a08 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,3 @@ +poetry +nox +pytest