From f18f78f42e2153bb2e5eb35d9026bc0fece0bcc9 Mon Sep 17 00:00:00 2001 From: Trenton H <797416+stumpylog@users.noreply.github.com> Date: Tue, 24 Sep 2024 16:11:58 -0700 Subject: [PATCH] Reworks workflows, add trusted publishing, and add editor config files (#35) --- .editorconfig | 32 +++ .github/workflows/ci.yml | 254 +++++++++++++++++++++ .github/workflows/publish-develop-docs.yml | 27 --- .github/workflows/publish-py.yml | 32 --- .github/workflows/publish-release-docs.yml | 27 --- .github/workflows/test-docs.yml | 29 --- .github/workflows/test-src.yml | 93 -------- .gitignore | 3 - .vscode/extensions.json | 3 + CHANGELOG.md | 25 +- docs/src/contributing.md | 2 +- 11 files changed, 309 insertions(+), 218 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/publish-develop-docs.yml delete mode 100644 .github/workflows/publish-py.yml delete mode 100644 .github/workflows/publish-release-docs.yml delete mode 100644 .github/workflows/test-docs.yml delete mode 100644 .github/workflows/test-src.yml create mode 100644 .vscode/extensions.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..554186bc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,32 @@ +# EditorConfig: http://EditorConfig.org + +root = true + +[*] +indent_style = tab +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +charset = utf-8 +max_line_length = 120 + +[{*.html,*.css,*.js}] +max_line_length = off + +[*.py] +indent_size = 4 +indent_style = space + +[*.{yml,yaml}] +indent_style = space +indent_size = 4 + +[*.{rst, md}] +indent_style = space + +# Tests don't get a line width restriction. It's still a good idea to follow +# the 99 character rule, but in the interests of clarity, tests often need to +# violate it. +[**/test_*.py] +max_line_length = off diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..f10d4be3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,254 @@ +name: CI + +on: + push: + pull_request: + branches: + - main + +concurrency: + group: ci-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + code-lint: + name: Code Linting + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.x + uses: actions/setup-python@v5 + with: + python-version: '3.x' + cache: 'pip' + - name: Install Hatch + run: | + pip3 --quiet install --upgrade hatch uv + hatch --version + uv --version + - name: Lint project + run: | + hatch fmt --check + - name: Check files with pre-commit + uses: pre-commit/action@v3.0.1 + + docs-lint: + name: Documentation Linting + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + cache: pip + - name: Install dependecies + run: | + pip install --upgrade hatch uv + - name: Check documentation links + if: false + run: | + hatch run docs:linkcheck + - name: Check docs build + run: | + hatch run docs:build + + tests: + name: Python ${{ matrix.python-version }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + needs: + - code-lint + + strategy: + matrix: + os: + - ubuntu-latest + - windows-latest + python-version: + - "3.9" + - "3.10" + - "3.11" + - "3.12" + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + cache: pip + + - name: Install dependencies + run: | + python -m pip install --upgrade pip hatch uv + + - name: Show environment + run: | + hatch test --show --python ${{ matrix.python-version }} + + - name: Run tests + run: | + hatch test --cover --python ${{ matrix.python-version }} + mv .coverage ".coverage.py${{ matrix.python-version }}" + + - name: Upload coverage data + if: matrix.os != 'windows-latest' + uses: actions/upload-artifact@v4 + with: + name: "coverage-data-py${{ matrix.python-version }}" + path: ".coverage.py${{ matrix.python-version }}" + if-no-files-found: error + include-hidden-files: true + retention-days: 7 + + build: + name: Build Distributions + runs-on: ubuntu-latest + permissions: + contents: read + needs: + - code-lint + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.x + uses: actions/setup-python@v5 + with: + python-version: '3.x' + cache: 'pip' + - name: Install Hatch + run: | + pip3 --quiet install --upgrade hatch uv + hatch --version + uv --version + - name: Build release files + run: | + hatch build --clean + - uses: actions/upload-artifact@v4 + with: + name: artifacts + path: dist/* + if-no-files-found: error + retention-days: 7 + + coverage: + name: Coverage + runs-on: ubuntu-latest + needs: + - tests + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + cache: pip + + - name: Install dependencies + run: python -m pip install --upgrade coverage[toml] + + - name: Download data + uses: actions/download-artifact@v4 + with: + merge-multiple: true + + - name: Combine coverage and fail if it's <95% + run: | + python -m coverage combine + python -m coverage html --skip-covered --skip-empty + python -m coverage report --fail-under=95 + + - name: Upload HTML report + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: html-report + path: htmlcov + + docs-deploy: + name: Deploy Documentation + runs-on: ubuntu-latest + needs: + - docs-lint + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + cache: pip + - name: Install dependecies + run: | + pip install --upgrade hatch uv + - name: Configure Git + run: | + git config user.name github-actions + git config user.email github-actions@github.com + - name: Publish Develop Docs + if: github.ref_name == 'main' + run: | + hatch run docs:deploy_develop + - name: Publish Develop Docs + if: startsWith(github.ref, 'refs/tags/') + run: | + hatch run docs:deploy_latest ${{ github.ref_name }} + + create-release: + name: Create Release + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: write + needs: + - build + - tests + - docs-deploy + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/download-artifact@v4 + with: + name: artifacts + path: dist + - name: Get latest release info + id: query-release-info + uses: release-flow/keep-a-changelog-action@v3 + with: + command: query + version: ${{ github.ref_name }} + - name: Display release info + run: | + echo "Version: ${{ steps.query-release-info.outputs.version }}" + echo "Date: ${{ steps.query-release-info.outputs.release-date }}" + echo "${{ steps.query-release-info.outputs.release-notes }}" + - uses: ncipollo/release-action@v1 + with: + artifacts: "dist/*.tar.gz,dist/*.whl" + body: ${{ steps.query-release-info.outputs.release-notes }} + + pypi-publish: + name: Publish to PyPi + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + needs: + - build + - tests + - docs-deploy + steps: + - uses: actions/download-artifact@v4 + with: + name: artifacts + path: dist + - name: Publish build to PyPI + uses: pypa/gh-action-pypi-publish@v1.10.1 diff --git a/.github/workflows/publish-develop-docs.yml b/.github/workflows/publish-develop-docs.yml deleted file mode 100644 index 1b3afba4..00000000 --- a/.github/workflows/publish-develop-docs.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Publish Develop Docs - -on: - push: - branches: - - main -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-python@v5 - with: - python-version: 3.x - cache: pip - - name: Install dependecies - run: | - pip install --upgrade hatch uv - - name: Publish Develop Docs - run: | - git config user.name github-actions - git config user.email github-actions@github.com - hatch run docs:deploy_develop - concurrency: - group: publish-docs diff --git a/.github/workflows/publish-py.yml b/.github/workflows/publish-py.yml deleted file mode 100644 index afa591f8..00000000 --- a/.github/workflows/publish-py.yml +++ /dev/null @@ -1,32 +0,0 @@ -# This workflows will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -name: Publish Python - -on: - release: - types: [published] - -jobs: - release-package: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.x" - cache: pip - - name: Install dependecies - run: | - pip install --upgrade hatch uv - - name: Build - run: | - hatch build --clean - # TODO: Update trusted publishing with pypa/gh-action-pypi-publish - - name: Publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - twine upload dist/* diff --git a/.github/workflows/publish-release-docs.yml b/.github/workflows/publish-release-docs.yml deleted file mode 100644 index d4bd1030..00000000 --- a/.github/workflows/publish-release-docs.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Publish Release Docs - -on: - release: - types: [published] - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-python@v5 - with: - python-version: 3.x - cache: pip - - name: Install dependecies - run: | - pip install --upgrade hatch uv - - name: Publish ${{ github.event.release.name }} Docs - run: | - git config user.name github-actions - git config user.email github-actions@github.com - hatch run docs:deploy_latest ${{ github.event.release.name }} - concurrency: - group: publish-docs diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml deleted file mode 100644 index 8c4f9cd8..00000000 --- a/.github/workflows/test-docs.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Test Docs - -on: - pull_request: - branches: - - main - schedule: - - cron: "0 0 * * *" - -jobs: - docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-python@v5 - with: - python-version: 3.x - cache: pip - - name: Install dependecies - run: | - pip install --upgrade hatch uv - - name: Check documentation links - run: | - hatch run docs:linkcheck - - name: Check docs build - run: | - hatch run docs:build diff --git a/.github/workflows/test-src.yml b/.github/workflows/test-src.yml deleted file mode 100644 index 4769549c..00000000 --- a/.github/workflows/test-src.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Test Code - -on: - push: - branches: - - main - pull_request: - branches: - - main - -concurrency: - group: ${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - tests: - name: Python ${{ matrix.python-version }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: - - ubuntu-latest - - windows-latest - python-version: - - "3.9" - - "3.10" - - "3.11" - - "3.12" - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - cache: pip - - - name: Install dependencies - run: | - python -m pip install --upgrade pip hatch uv - - - name: Show environment - run: | - hatch test --show --python ${{ matrix.python-version }} - - - name: Run tests - run: | - hatch test --cover --python ${{ matrix.python-version }} - mv .coverage ".coverage.py${{ matrix.python-version }}" - - - name: Upload coverage data - if: matrix.os != 'windows-latest' - uses: actions/upload-artifact@v4 - with: - name: "coverage-data-py${{ matrix.python-version }}" - path: ".coverage.py${{ matrix.python-version }}" - if-no-files-found: error - include-hidden-files: true - - coverage: - name: Coverage - runs-on: ubuntu-latest - needs: tests - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: "3.11" - cache: pip - - - name: Install dependencies - run: python -m pip install --upgrade coverage[toml] - - - name: Download data - uses: actions/download-artifact@v4 - with: - merge-multiple: true - - - name: Combine coverage and fail if it's <95% - run: | - python -m coverage combine - python -m coverage html --skip-covered --skip-empty - python -m coverage report --fail-under=95 - - - name: Upload HTML report - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: html-report - path: htmlcov diff --git a/.gitignore b/.gitignore index a32447f7..78418868 100644 --- a/.gitignore +++ b/.gitignore @@ -122,12 +122,9 @@ Control.system-ca-bundle GitHub.sublime-settings # Visual Studio Code # -.vscode -.vscode/* .vscode/settings.json .vscode/tasks.json .vscode/launch.json -.vscode/extensions.json .history %SystemDrive% diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..4d9a3df5 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": [ "ms-python.python", "charliermarsh.ruff", "editorconfig.editorconfig" ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index f2987832..71925b60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,17 +32,19 @@ Using the following categories, list your changes in this order: -## [Unreleased](https://github.com/Archmonger/ServeStatic/compare/2.0.1...HEAD) +## [Unreleased] + - Nothing (yet)! -## [2.0.1](https://github.com/Archmonger/ServeStatic/compare/2.0.0...2.0.1) - 2024-09-13 +## [2.0.1] - 2024-09-13 + ### Fixed - Fix crash when running `manage.py collectstatic` when Django's `settings.py:STATIC_ROOT` is a `Path` object. -## [2.0.0](https://github.com/Archmonger/ServeStatic/compare/1.2.0...2.0.0) - 2024-09-12 +## [2.0.0] - 2024-09-12 ### Added @@ -58,7 +60,8 @@ Using the following categories, list your changes in this order: - `AsgiFileServer` has been renamed to `FileServerASGI`. - Lots of internal refactoring to improve performance, code quality, and maintainability. -## [1.2.0](https://github.com/Archmonger/ServeStatic/compare/1.1.0...1.2.0) - 2024-08-30 +## [1.2.0] - 2024-08-30 + ### Added @@ -70,7 +73,8 @@ Using the following categories, list your changes in this order: - ServeStatic Django middleware now only runs in async mode to avoid clashing with Django's internal usage of `asgiref.AsyncToSync`. - Respect Django `settings.py:FORCE_SCRIPT_NAME` configuration value. -## [1.1.0](https://github.com/Archmonger/ServeStatic/compare/1.0.0...1.1.0) - 2024-08-27 +## [1.1.0] - 2024-08-27 + ### Added @@ -81,8 +85,17 @@ Using the following categories, list your changes in this order: - Fix Django `StreamingHttpResponse must consume synchronous iterators` warning. - Fix Django bug where file paths could fail to be followed on Windows. -## [1.0.0](https://github.com/Archmonger/ServeStatic/releases/tag/1.0.0) - 2024-05-08 +## [1.0.0] - 2024-05-08 + ### Changed - Forked from [`whitenoise`](https://github.com/evansd/whitenoise) to add ASGI support. + + +[Unreleased](https://github.com/Archmonger/ServeStatic/compare/2.0.1...HEAD) +[2.0.1](https://github.com/Archmonger/ServeStatic/compare/2.0.0...2.0.1) +[2.0.0](https://github.com/Archmonger/ServeStatic/compare/1.2.0...2.0.0) +[1.2.0](https://github.com/Archmonger/ServeStatic/compare/1.1.0...1.2.0) +[1.1.0](https://github.com/Archmonger/ServeStatic/compare/1.0.0...1.1.0) +[1.0.0](https://github.com/Archmonger/ServeStatic/releases/tag/1.0.0) diff --git a/docs/src/contributing.md b/docs/src/contributing.md index 007407eb..f9648027 100644 --- a/docs/src/contributing.md +++ b/docs/src/contributing.md @@ -31,7 +31,7 @@ By utilizing `hatch`, the following commands are available to manage the develop The `hatch test` command is a wrapper for `pytest`. Hatch "intercepts" a handful of arguments, which can be previewed by typing `hatch test --help`. - Any additional arguments in the `test` command are directly passed on to pytest. See the [pytest documentation](https://docs.pytest.org/en/8.3.x/reference/reference.html#command-line-flags) for what additional arguments are available. + Any additional arguments in the `test` command are directly passed on to pytest. See the [pytest documentation](https://docs.pytest.org/en/stable/reference/reference.html#command-line-flags) for what additional arguments are available. ### Linting and Formatting