diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 16598a700..000000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -max-line-length = 99 -ignore = E731,E203 diff --git a/.github/workflows/python-check.yaml b/.github/workflows/python-check.yaml new file mode 100644 index 000000000..4e4b473d2 --- /dev/null +++ b/.github/workflows/python-check.yaml @@ -0,0 +1,112 @@ +name: Python Check +run-name: "${{ github.actor }} checking Python code" + +on: + pull_request: + branches: [ main ] + workflow_dispatch: + +jobs: + detect-python-changes: + runs-on: ubuntu-latest + permissions: + contents: read + + outputs: + has_changes: ${{ steps.filter.outputs.matched }} + changed_files: ${{ steps.filter.outputs.matched_files }} + is_act: ${{ steps.detect_act.outputs.is_act }} + + steps: + - name: Checkout code + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + fetch-depth: 0 + path: phlex-src + + - name: Detect act environment + id: detect_act + uses: ./phlex-src/.github/actions/detect-act-env + + - name: Detect Python changes + id: filter + uses: Framework-R-D/phlex/.github/actions/detect-relevant-changes@main + with: + repo-path: phlex-src + base-ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} + head-ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + file-type: python + + - name: Report detection outcome + run: | + if [ "${{ steps.filter.outputs.matched }}" != "true" ]; then + echo "::notice::No python check relevant changes detected; workflow will be skipped." + else + echo "::group::Python check relevant files" + printf '%s\n' "${{ steps.filter.outputs.matched_files }}" + echo "::endgroup::" + fi + + python-check: + needs: detect-python-changes + if: ${{ (needs.detect-python-changes.outputs.has_changes == 'true') || (github.event_name == 'workflow_dispatch') || (needs.detect-python-changes.outputs.is_act == 'true') }} + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + path: phlex-src + + - name: Set up Python + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: '3.x' + + - name: Install Python dependencies + run: | + pip install ruff mypy + + - name: Run ruff and mypy checks + working-directory: phlex-src + env: + FORCE_COLOR: 1 # `ruff`/`colored` crate + run: | + failed=0 + + echo "➡️ Checking Python code with ruff..." + echo "::group::Running ruff check" + if ! ruff check; then + failed=1 + echo "::endgroup::" + echo "❌ Ruff check failed." + else + echo "::endgroup::" + echo "✅ Ruff check passed." + fi + + echo "➡️ Checking Python code with mypy..." + echo "::group::Running mypy" + if ! mypy --color-output .; then + failed=1 + echo "::endgroup::" + echo "❌ MyPy check failed." + else + echo "::endgroup::" + echo "✅ MyPy check passed." + fi + + exit $failed + + python-check-skipped: + needs: detect-python-changes + if: ${{ (needs.detect-python-changes.outputs.has_changes != 'true') && (github.event_name != 'workflow_dispatch') && (needs.detect-python-changes.outputs.is_act != 'true') }} + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: No relevant Python changes detected + run: echo "No Python relevant changes detected; check skipped." diff --git a/.github/workflows/python-fix.yaml b/.github/workflows/python-fix.yaml new file mode 100644 index 000000000..e0ca1d1ae --- /dev/null +++ b/.github/workflows/python-fix.yaml @@ -0,0 +1,92 @@ +name: Python Fix +run-name: "${{ github.actor }} fixing Python code" + +on: + issue_comment: + types: + - created + +permissions: + pull-requests: write + contents: write + +jobs: + parse-command: + runs-on: ubuntu-latest + name: Parse bot command + if: ${{ github.event.issue.pull_request }} + outputs: + should_run: ${{ steps.check_comment.outputs.should_run }} + ref: ${{ steps.get_pr.outputs.ref }} + sha: ${{ steps.get_pr.outputs.sha }} + repo: ${{ steps.get_pr.outputs.repo }} + + steps: + - id: check_comment + name: Check comment for trigger phrase + run: | + if [[ "${{ github.event.comment.author_association }}" == "COLLABORATOR" || "${{ github.event.comment.author_association }}" == "OWNER" ]] && \ + [[ $(echo "${{ github.event.comment.body }}" | grep -qEe '^@phlexbot[[:space:]]+python-fix\b' && echo 'true') ]]; then + echo "should_run=true" >> $GITHUB_OUTPUT + else + echo "should_run=false" >> $GITHUB_OUTPUT + fi + - name: Get PR Info + if: steps.check_comment.outputs.should_run == 'true' + id: get_pr + uses: ./actions/get-pr-info + + apply_fixes: + runs-on: ubuntu-latest + name: Apply fixes + needs: parse-command + if: ${{ needs.parse-command.outputs.should_run == 'true' }} + steps: + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + path: phlex-src + ref: ${{ needs.parse-command.outputs.ref }} + repository: ${{ needs.parse-command.outputs.repo }} + token: ${{ secrets.WORKFLOW_PAT }} + + - name: Set up Python + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: '3.x' + + - name: Install Python dependencies + run: | + pip install ruff + + - name: Run ruff format and fix + working-directory: phlex-src + env: + FORCE_COLOR: 1 + run: | + echo "Fixing Python format with ruff" + ruff format . || true + echo "Fixing Python linter issues with ruff" + ruff --fix . || true + + - uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 + id: add_and_commit + with: + token: ${{ secrets.WORKFLOW_PAT }} + cwd: phlex-src + author_name: "github-actions[bot]" + author_email: "41898282+github-actions[bot]@users.noreply.github.com" + message: 'Committing Python linting fixes' + + - name: Formatting changes committed and pushed + if: ${{ steps.add_and_commit.outputs.committed == 'true' && steps.add_and_commit.outputs.pushed == 'true'}} + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1 + with: + message: | + Python linting fixes pushed (commit ${{ steps.add_and_commit.outputs.commit_sha }}) + + - name: No formatting changes to make + if: ${{ steps.add_and_commit.outputs.committed == 'false' }} + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1 + with: + message: | + No Python linting fixes to make diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..9357828e5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,34 @@ +[tool.mypy] +ignore_missing_imports = true +no_implicit_optional = true +plugins = [ +] +show_error_codes = true +warn_unreachable = true +disable_error_code = "annotation-unchecked" + +[tool.ruff] +target-version = "py310" +line-length = 99 + +[tool.ruff.lint] +select = [ + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "D", # pydocstyle + "E", # pycodestyle errors + "F", # pyflakes + "I", # isort + "W", # pycodestyle warnings +] +ignore = [] +extend-ignore = [ + "E731", # do not assign a lambda expression, use a def + "E203", # whitespace before ':' +] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.format] +quote-style = "double"