fix: resolve code scanning alerts #119
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| # Skip CI for docs-only and metadata changes on push to main | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - 'examples/**' | |
| - '.github/**' | |
| - '!.github/workflows/**' | |
| - '.gitignore' | |
| pull_request: | |
| branches: [main] | |
| # Cancel in-progress runs when a new workflow with the same group name starts | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| # Set read-only permissions by default | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: Lint and format check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | |
| with: | |
| python-version: "3.14" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v7 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: "pyproject.toml" | |
| - name: Install dependencies | |
| run: uv sync --extra dev | |
| - name: Run ruff check | |
| run: uv run ruff check peakbagger tests | |
| - name: Run ruff format check | |
| run: uv run ruff format --check peakbagger tests | |
| typecheck: | |
| name: Typecheck | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | |
| with: | |
| python-version: "3.14" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v7 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: "pyproject.toml" | |
| - name: Install dependencies | |
| run: uv sync --extra dev | |
| - name: Run ty | |
| run: uvx ty check peakbagger | |
| test: | |
| name: Test on ${{ matrix.os }} - Python ${{ matrix.python-version }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest] | |
| python-version: ["3.12", "3.13", "3.14"] | |
| include: | |
| # Smoke tests on macOS and Windows with latest Python | |
| - os: macos-latest | |
| python-version: "3.14" | |
| - os: windows-latest | |
| python-version: "3.14" | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v7 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: "pyproject.toml" | |
| - name: Install dependencies | |
| run: uv sync --extra dev | |
| - name: Run tests with coverage | |
| run: uv run pytest --cov=peakbagger --cov-report=xml --cov-report=term --cov-fail-under=85 | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14' | |
| uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| file: ./coverage.xml | |
| fail_ci_if_error: false | |
| sast: | |
| name: SAST | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 | |
| - name: Install Semgrep | |
| run: pip install semgrep==1.139.0 | |
| - name: Run Semgrep | |
| run: semgrep scan --config auto --error . | |
| complexity: | |
| name: Complexity | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 | |
| - name: Install lizard | |
| run: pip install lizard==1.17.13 | |
| - name: Check complexity | |
| run: lizard -l python -C 15 -L 60 -a 5 -w -x 'test_*.py' -x '*_test.py' -x '*/cli.py' peakbagger/ | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5 | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | |
| with: | |
| python-version: "3.14" | |
| cache: pip | |
| cache-dependency-path: pyproject.toml | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v7 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: "pyproject.toml" | |
| - run: uv build | |
| validate-pr-title: | |
| name: Validate PR title | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Validate PR title follows conventional commit format | |
| uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| types: | | |
| feat | |
| fix | |
| docs | |
| style | |
| refactor | |
| perf | |
| test | |
| chore | |
| ci | |
| build | |
| requireScope: false | |
| subjectPattern: ^.+$ | |
| subjectPatternError: | | |
| The subject "{subject}" found in the PR title "{title}" | |
| must not be empty. | |
| validateSingleCommit: false | |
| ignoreLabels: | | |
| bot | |
| dependencies | |
| # Sentinel job - the ONLY required check in branch protection | |
| required-checks: | |
| name: Required Checks | |
| runs-on: ubuntu-latest | |
| needs: [lint, typecheck, test, sast, complexity, build, validate-pr-title] | |
| if: always() | |
| steps: | |
| - name: Check results | |
| run: | | |
| results=("${{ needs.lint.result }}" "${{ needs.typecheck.result }}" \ | |
| "${{ needs.test.result }}" "${{ needs.sast.result }}" \ | |
| "${{ needs.complexity.result }}" "${{ needs.build.result }}") | |
| for result in "${results[@]}"; do | |
| if [[ "$result" == "failure" || "$result" == "cancelled" ]]; then | |
| echo "Required job failed or was cancelled: $result" | |
| exit 1 | |
| fi | |
| done | |
| # PR title validation must pass if it ran | |
| pr_result="${{ needs.validate-pr-title.result }}" | |
| if [[ "$pr_result" == "failure" || "$pr_result" == "cancelled" ]]; then | |
| echo "PR title validation failed" | |
| exit 1 | |
| fi | |
| echo "All required checks passed" |