diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8e453a..ca49b43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,6 @@ on: - main pull_request: -permissions: write-all - concurrency: group: ${{ github.head_ref || github.run_id }} cancel-in-progress: true @@ -16,11 +14,11 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 # Make sure commit messages follow the conventional commits convention: # https://www.conventionalcommits.org @@ -28,10 +26,10 @@ jobs: name: Lint Commit Messages runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: wagoid/commitlint-github-action@v5.3.1 + - uses: wagoid/commitlint-github-action@v6 test: strategy: @@ -45,115 +43,184 @@ jobs: os: - ubuntu-latest - macOS-latest + - windows-latest extension: - "skip_cython" - "use_cython" runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - uses: snok/install-poetry@v1.3.3 + allow-prereleases: true + - uses: snok/install-poetry@v1.4.1 - name: Install Dependencies run: | if [ "${{ matrix.extension }}" = "skip_cython" ]; then - SKIP_CYTHON=1 poetry install --only=main,dev -v + SKIP_CYTHON=1 poetry install --only=main,dev else - poetry install --only=main,dev -v + poetry install --only=main,dev fi shell: bash - name: Test with Pytest - run: poetry run pytest --cov-report=xml + run: poetry run pytest --cov-report=xml -v -Wdefault --cov=bluetooth_data_tools --cov-report=term-missing:skip-covered tests shell: bash - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} release: - runs-on: ubuntu-latest - environment: release - outputs: - newest_release_tag: ${{ steps.release_tag.outputs.newest_release_tag }} - if: github.ref == 'refs/heads/main' needs: - test - lint - commitlint + runs-on: ubuntu-latest + environment: release + concurrency: release + permissions: + id-token: write + contents: write + outputs: + released: ${{ steps.release.outputs.released }} + newest_release_tag: ${{ steps.release.outputs.tag }} + steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 + ref: ${{ github.head_ref || github.ref_name }} - # Run semantic release: - # - Update CHANGELOG.md - # - Update version in code - # - Create git tag - # - Create GitHub release - # - Publish to PyPI - - name: Python Semantic Release - uses: python-semantic-release/python-semantic-release@v7.34.6 + # Do a dry run of PSR + - name: Test release + uses: python-semantic-release/python-semantic-release@v9.21.0 + if: github.ref_name != 'main' + with: + root_options: --noop + + # On main branch: actual PSR + upload to PyPI & GitHub + - name: Release + uses: python-semantic-release/python-semantic-release@v9.21.0 + id: release + if: github.ref_name == 'main' with: github_token: ${{ secrets.GITHUB_TOKEN }} - pypi_token: ${{ secrets.PYPI_TOKEN }} - - name: Install python-semantic-release - run: python3 -m pip install python-semantic-release==7.34.6 + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + if: steps.release.outputs.released == 'true' - - name: Get Release Tag - id: release_tag - shell: bash - run: | - echo "newest_release_tag=$(semantic-release print-version --current)" >> $GITHUB_OUTPUT + - name: Publish package distributions to GitHub Releases + uses: python-semantic-release/upload-to-gh-release@main + if: steps.release.outputs.released == 'true' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} build_wheels: needs: [release] - - name: Build wheels on ${{ matrix.os }} + if: needs.release.outputs.released == 'true' + name: Wheels for ${{ matrix.os }} (${{ matrix.musl == 'musllinux' && 'musllinux' || 'manylinux' }}) ${{ matrix.qemu }} ${{ matrix.pyver }} runs-on: ${{ matrix.os }} strategy: matrix: os: - - ubuntu-24.04-arm - - macos-latest - - ubuntu-latest - - windows-latest - musl: ["", "musllinux"] - exclude: - - os: windows-latest + [ + windows-latest, + ubuntu-24.04-arm, + ubuntu-latest, + macos-13, + macos-latest, + ] + qemu: [""] + musl: [""] + pyver: [""] + include: + - os: ubuntu-latest + musl: "musllinux" + - os: ubuntu-24.04-arm musl: "musllinux" - - os: macos-latest + # qemu is slow, make a single + # runner per Python version + - os: ubuntu-latest + qemu: armv7l musl: "musllinux" + pyver: cp310 + - os: ubuntu-latest + qemu: armv7l + musl: "musllinux" + pyver: cp311 + - os: ubuntu-latest + qemu: armv7l + musl: "musllinux" + pyver: cp312 + - os: ubuntu-latest + qemu: armv7l + musl: "musllinux" + pyver: cp313 + # qemu is slow, make a single + # runner per Python version + - os: ubuntu-latest + qemu: armv7l + musl: "" + pyver: cp310 + - os: ubuntu-latest + qemu: armv7l + musl: "" + pyver: cp311 + - os: ubuntu-latest + qemu: armv7l + musl: "" + pyver: cp312 + - os: ubuntu-latest + qemu: armv7l + musl: "" + pyver: cp313 steps: - uses: actions/checkout@v4 with: - ref: "v${{ needs.release.outputs.newest_release_tag }}" + ref: ${{ needs.release.outputs.newest_release_tag }} fetch-depth: 0 - # Used to host cibuildwheel - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: - python-version: "3.10" - - - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.22.0 - + python-version: "3.12" + - name: Set up QEMU + if: ${{ matrix.qemu }} + uses: docker/setup-qemu-action@v3 + with: + platforms: all + # This should be temporary + # xref https://github.com/docker/setup-qemu-action/issues/188 + # xref https://github.com/tonistiigi/binfmt/issues/215 + image: tonistiigi/binfmt:qemu-v8.1.5 + id: qemu + - name: Prepare emulation + if: ${{ matrix.qemu }} + run: | + if [[ -n "${{ matrix.qemu }}" ]]; then + # Build emulated architectures only if QEMU is set, + # use default "auto" otherwise + echo "CIBW_ARCHS_LINUX=${{ matrix.qemu }}" >> $GITHUB_ENV + fi + - name: Limit to a specific Python version on slow QEMU + if: ${{ matrix.pyver }} + run: | + if [[ -n "${{ matrix.pyver }}" ]]; then + echo "CIBW_BUILD=${{ matrix.pyver }}*" >> $GITHUB_ENV + fi - name: Build wheels - run: python -m cibuildwheel --output-dir wheelhouse - # to supply options, put them in 'env', like: + uses: pypa/cibuildwheel@v2.23.0 env: - CIBW_SKIP: cp36-* cp37-* cp38-* cp39-* pp36-* pp37-* pp38-* pp39-* ${{ matrix.musl == 'musllinux' && '*manylinux*' || '*musllinux*' }} - CIBW_BEFORE_ALL_LINUX: apt-get install -y gcc || yum install -y gcc || apk add gcc - CIBW_BUILD_VERBOSITY: 3 + CIBW_SKIP: cp36-* cp37-* cp38-* cp39-* pp* ${{ matrix.musl == 'musllinux' && '*manylinux*' || '*musllinux*' }} REQUIRE_CYTHON: 1 - CIBW_ARCHS_LINUX: ${{ matrix.os == 'ubuntu-24.04-arm' && 'aarch64' || 'auto' }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: + name: wheels-${{ matrix.os }}-${{ matrix.musl }}-${{ matrix.pyver }}-${{ matrix.qemu }} path: ./wheelhouse/*.whl upload_pypi: @@ -162,14 +229,15 @@ jobs: environment: release steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: # unpacks default artifact into dist/ # if `name: artifact` is omitted, the action will create extra parent dir - name: artifact path: dist + pattern: wheels-* + merge-multiple: true - - uses: pypa/gh-action-pypi-publish@v1.5.0 + - uses: pypa/gh-action-pypi-publish@v1.12.4 with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} diff --git a/commitlint.config.js b/commitlint.config.mjs similarity index 92% rename from commitlint.config.js rename to commitlint.config.mjs index 8b82768..deb029a 100644 --- a/commitlint.config.js +++ b/commitlint.config.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { extends: ["@commitlint/config-conventional"], rules: { "header-max-length": [0, "always", Infinity], diff --git a/pyproject.toml b/pyproject.toml index 97f2e4c..a42a71a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,8 +38,8 @@ cython = ">=0.29.35,<3.1.0" [tool.semantic_release] branch = "main" -version_toml = "pyproject.toml:tool.poetry.version" -version_variable = "src/kasa_crypt/__init__.py:__version__" +version_toml = ["pyproject.toml:tool.poetry.version"] +version_variables = ["src/kasa_crypt/__init__.py:__version__"] build_command = "pip install poetry && poetry build" [tool.pytest.ini_options] @@ -81,5 +81,5 @@ module = "tests.*" allow_untyped_defs = true [build-system] -requires = ['setuptools>=65.4.1', 'wheel', 'Cython', "poetry-core>=1.0.0"] +requires = ['setuptools>=65.4.1', 'wheel', 'Cython>=3', "poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api"