Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jenstroeger/python-package-template
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.4.1
Choose a base ref
...
head repository: jenstroeger/python-package-template
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 2,210 additions and 1,271 deletions.
  1. +49 −2 .flake8
  2. +12 −0 .gitattributes
  3. +1 −2 .github/codeql/codeql-config.yaml
  4. +8 −0 .github/dependabot.yaml
  5. +142 −0 .github/workflows/_build.yaml
  6. +59 −0 .github/workflows/_generate-rebase.yaml
  7. +50 −0 .github/workflows/_release-notifications.yaml
  8. +92 −0 .github/workflows/_wiki-documentation.yaml
  9. +0 −62 .github/workflows/check-and-release-main.yaml
  10. +18 −12 .github/workflows/codeql-analysis.yaml
  11. +21 −0 .github/workflows/dependabot-automerge.yaml
  12. +23 −0 .github/workflows/pr-change-set.yaml
  13. +55 −0 .github/workflows/pr-conventional-commits.yaml
  14. +0 −63 .github/workflows/pull-request.yaml
  15. +0 −39 .github/workflows/release-notifications.yaml
  16. +275 −0 .github/workflows/release.yaml
  17. +13 −8 .github/workflows/scorecards-analysis.yaml
  18. +90 −0 .github/workflows/sync-with-upstream.yaml
  19. +0 −3 .gitignore
  20. +57 −40 .pre-commit-config.yaml
  21. +9 −0 .vscode/extensions.json
  22. +31 −0 .vscode/launch.json
  23. +34 −0 .vscode/settings.json
  24. +0 −1 CHANGELOG.md
  25. +395 −0 CHANGELOG.md
  26. +4 −0 CODEOWNERS
  27. +1 −1 LICENSE.md
  28. +0 −9 MANIFEST.in
  29. +176 −65 Makefile
  30. +0 −1 README.md
  31. +289 −0 README.md
  32. +17 −0 SECURITY.md
  33. +0 −12 UPSTREAM_CHANGELOG.md
  34. +0 −255 UPSTREAM_README.md
  35. +0 −7 commitlint.rules.js
  36. +3 −1 docs/Makefile
  37. +2 −1 docs/source/conf.py
  38. +12 −0 docs/source/index.rst
  39. +0 −37 mypy.ini
  40. +0 −536 pylintrc
  41. +243 −19 pyproject.toml
  42. +0 −90 setup.py
  43. +1 −1 src/package/__init__.py
  44. +2 −3 src/package/__main__.py
  45. +13 −1 src/package/something.py
  46. +13 −0 tests/conftest.py
51 changes: 49 additions & 2 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,5 +1,52 @@
# Unfortunately, flake8 does not support pyproject.toml configuration.
# Unfortunately, Flake8 does not support pyproject.toml configuration.
# https://github.com/PyCQA/flake8/issues/234
#
# More details regarding Flake8 and Black interplay:
# https://github.com/psf/black/blob/main/docs/guides/using_black_with_other_tools.md#flake8
[flake8]
show-source = true

# Enable a few additional checks.
#
# https://github.com/PyCQA/flake8-bugbear#how-to-enable-opinionated-warnings
# B9: Bugbear's extended opinionated checks
#
# https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
# W504: line break after binary operator (Black compliant)
extend-select = B9, W504

# Disable several warnings that don't play nice with PEP8 or Black,
# or that are a bit of a nuisance in general.
#
# http://www.pydocstyle.org/en/latest/error_codes.html
# D105: Missing docstring in magic method
#
# https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
# E203: whitespace before ‘,’, ‘;’, or ‘:’ (not Black compliant)
# E501: line too long (managed better by Bugbear's B950)
# W503: line break before binary operator (not Black compliant)
#
# https://github.com/peterjc/flake8-rst-docstrings#configuration
# RST307: Error in "XXX" directive
ignore = D105, E203, E501, RST307, W503
per-file-ignores =

# More assorted goodness.
max-line-length = 120
show-source = true

# Ensure that Flake8 warnings are silenced correctly:
# https://github.com/plinss/flake8-noqa#options
noqa-require-code = true

# Ensure that Sphinx extensions of .rst are recognized:
# https://github.com/peterjc/flake8-rst-docstrings#configuration
rst-roles = class, func, ref
rst-directives = envvar, exception
rst-substitutions = version

# Ensure that Sphinx docstrings use Numpy format for docstrings:
# https://github.com/PyCQA/flake8-docstrings
#
# For details on the Numpy format:
# https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html
docstring-convention = numpy
12 changes: 12 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Set default behavior to automatically normalize line endings.
* text=auto

# Force batch scripts to always use CRLF line endings so that if a repo is accessed
# in Windows via a file share from Linux, the scripts will work.
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.{ps1,[pP][sS]1} text eol=crlf

# Force bash scripts to always use LF line endings so that if a repo is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lf
3 changes: 1 addition & 2 deletions .github/codeql/codeql-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
name: CodeQL config

name: CodeQL configuration
paths:
- src/package
8 changes: 8 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -14,6 +14,10 @@ updates:
include: scope
open-pull-requests-limit: 13
target-branch: staging
# Add additional reviewers for PRs opened by Dependabot. For more information, see:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#reviewers
# reviewers:
# -

- package-ecosystem: github-actions
directory: /
@@ -25,3 +29,7 @@ updates:
include: scope
open-pull-requests-limit: 13
target-branch: staging
# Add additional reviewers for PRs opened by Dependabot. For more information, see:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#reviewers
# reviewers:
# -
142 changes: 142 additions & 0 deletions .github/workflows/_build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# This is a trusted builder implemented as a reusable workflow that can be called by other
# Actions workflows. It checks, tests, and builds the artifacts including SBOM and documentations,
# and computes hash digests as output to be used by a SLSA provenance generator. The artifacts are
# always uploaded for every job to be used for debugging purposes, but they will be removed within
# the specified retention days.
#
# Even though we run the build in a matrix to check against different platforms, due to a known
# limitation of reusable workflows that do not support setting strategy property from the caller
# workflow, we only generate artifacts for ubuntu-latest and Python 3.13, which can be used to
# create a release. For details see:
#
# https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations
#
# Note: if the build workflow needs to access secrets, they need to be passed by the caller using
# `secrets: inherit`. See also
#
# https://docs.github.com/en/actions/using-workflows/reusing-workflows
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions
#
# for the security recommendations.

name: Build the package
on:
workflow_call:
inputs:
disable-pip-audit:
type: boolean
required: true
description: Enable or disable running pip_audit to check installed packages for vulnerabilities
outputs:
artifacts-sha256:
value: ${{ jobs.build.outputs.artifacts-sha256 }}
description: The hash of the artifacts
permissions:
contents: read
env:
ARTIFACT_OS: ubuntu-latest # The default OS for release.
ARTIFACT_PYTHON: '3.13' # The default Python version for release.

jobs:
build:
# Uncomment the following to disable checks and tests for Draft pull requests.
# if: github.event.pull_request.draft == false
outputs:
artifacts-sha256: ${{ steps.compute-hash.outputs.artifacts-sha256 }}
name: Build Python ${{ matrix.python }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# It is recommended to pin a Runner version specifically:
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
os: [ubuntu-latest, macos-latest, windows-latest]
python: ['3.10', '3.11', '3.12', '3.13']
steps:

- name: Harden Runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true

- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: ${{ matrix.python }}

# Using the Makefile assumes an activated virtual environment, which doesn't exist
# when running in an Action environment (https://github.com/actions/setup-python/issues/359).
# Instead we create an empty .venv folder so that the Makefile continues to function
# while Python operates within the runner's global environment. It is safe to ignore
# warnings from the Makefile about the missing virtual environment.
- name: Create empty virtual environment for Actions
run: mkdir .venv
- name: Install dependencies
run: make setup

# Audit all currently installed packages for security vulnerabilities. This step can
# be disabled by setting the repository variable DISABLE_PIP_AUDIT to 'true'.
- name: Audit installed packages
if: ${{ !inputs.disable-pip-audit }}
run: make audit

# Build the sdist and wheel distribution of the package and docs as a zip file.
# We don't need to check and test the package separately because `make dist` runs
# those targets first and only builds the package if they succeed. The Hypothesis
# profile picks the Hypothesis settings (see tests/conftest.py) which, for Github,
# disable randomized testing to avoid breaking CI.
- name: Build the package
run: make dist
env:
HYPOTHESIS_PROFILE: github

# Generate the requirements.txt that contains the hash digests of the dependencies and
# generate the SBOM using CyclonDX SBOM generator.
- name: Generate requirements.txt and SBOM
if: matrix.os == env.ARTIFACT_OS && matrix.python == env.ARTIFACT_PYTHON
run: make requirements sbom

# Remove the old requirements.txt file (which includes _all_ packages) and generate a
# new one for the package and its actual and required dependencies only.
- name: Prune packages and generate required requirements.txt
if: matrix.os == env.ARTIFACT_OS && matrix.python == env.ARTIFACT_PYTHON
run: |
rm requirements.txt
make prune requirements
# Find the paths to the artifact files that will be included in the release, compute
# the SHA digest for all the release files and encode them using Base64, and export it
# from this job.
- name: Compute package hash
if: matrix.os == env.ARTIFACT_OS && matrix.python == env.ARTIFACT_PYTHON
id: compute-hash
shell: bash
run: |
set -euo pipefail
TARBALL_PATH=$(find dist/ -type f -name "*.tar.gz")
WHEEL_PATH=$(find dist/ -type f -name "*.whl")
REQUIREMENTS_PATH=$(find dist/ -type f -name "*-requirements.txt")
SBOM_PATH=$(find dist/ -type f -name "*-sbom.json")
HTML_DOCS_PATH=$(find dist/ -type f -name "*-docs-html.zip")
MARKDOWN_DOCS_PATH=$(find dist/ -type f -name "*-docs-md.zip")
BUILD_EPOCH_PATH=$(find dist/ -type f -name "*-build-epoch.txt")
DIGEST=$(sha256sum "$TARBALL_PATH" "$WHEEL_PATH" "$REQUIREMENTS_PATH" "$SBOM_PATH" "$HTML_DOCS_PATH" "$MARKDOWN_DOCS_PATH" "$BUILD_EPOCH_PATH" | base64 -w0)
echo "Digest of artifacts is $DIGEST."
echo "artifacts-sha256=$DIGEST" >> "$GITHUB_OUTPUT"
# For now only generate artifacts for the specified OS and Python version in env variables.
# Currently reusable workflows do not support setting strategy property from the caller workflow.
- name: Upload the package artifact for debugging and release
if: matrix.os == env.ARTIFACT_OS && matrix.python == env.ARTIFACT_PYTHON
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
with:
name: artifact-${{ matrix.os }}-python-${{ matrix.python }}
path: dist
if-no-files-found: error
retention-days: 7
59 changes: 59 additions & 0 deletions .github/workflows/_generate-rebase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Automatically rebase one branch on top of another; usually staging on top
# of main after a new package version was published.

name: Rebase branch
on:
workflow_call:
inputs:
to-head:
type: string
required: true
description: Branch that is being rebased
from-base:
type: string
required: true
description: Base branch
git-user-name:
type: string
required: true
description: Name of the git user who rebases and pushes the to_head branch
git-user-email:
type: string
required: true
description: Email address of said git user
secrets:
REPO_ACCESS_TOKEN:
required: true

permissions:
contents: read

jobs:
rebase:
runs-on: ubuntu-latest
steps:

- name: Harden Runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs

- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
token: ${{ secrets.REPO_ACCESS_TOKEN }}
ref: ${{ github.ref_name }}

- name: Do rebase
run: |
git config --global user.name "$USER_NAME"
git config --global user.email "$USER_EMAIL"
git checkout "$TO_HEAD"
git rebase "$FROM_BASE"
git push --force-with-lease
env:
USER_NAME: ${{ inputs.git-user-name }}
USER_EMAIL: ${{ inputs.git-user-email }}
TO_HEAD: ${{ inputs.to-head }}
FROM_BASE: ${{ inputs.from-base }}
50 changes: 50 additions & 0 deletions .github/workflows/_release-notifications.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Send a Slack release notification. Instructions to set up Slack to receive
# messages can be found here: https://github.com/slackapi/slack-github-action#setup-2

name: Release Notifications
on:
workflow_call:
inputs:
repo-name:
type: string
required: true
description: Repository name used for the notification
release-tag:
type: string
required: true
description: Tag name of the release for the notification
release-url:
type: string
required: true
description: URL to the release page for the notification
secrets:
SLACK_WEBHOOK_URL:
required: true

# Grant no permissions to this workflow.
permissions: {}

jobs:
slack:
name: Slack release notification
runs-on: ubuntu-latest
steps:

- name: Notify via Slack
run: |
curl --header "Content-Type: application/json; charset=UTF-8" --request POST --data "$SLACK_WEBHOOK_MSG" "$SLACK_WEBHOOK_URL"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_MSG: |
{
"text": "${{ inputs.repo-name }} published a new release ${{ inputs.release-tag }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*${{ inputs.repo-name }}* published a new release <${{ inputs.release-url }}|${{ inputs.release-tag }}>"
}
}
]
}
Loading