diff --git a/.ansible-lint b/.ansible-lint index 0e80b05..4ffc0ef 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,10 +1,9 @@ --- -# See https://ansible-lint.readthedocs.io/en/latest/configuring.html -# for a list of the configuration elements that can exist in this -# file. +# See https://ansible-lint.readthedocs.io/configuring/ for a list of +# the configuration elements that can exist in this file. enable_list: # Useful checks that one must opt-into. See here for more details: - # https://ansible-lint.readthedocs.io/en/latest/rules.html + # https://ansible-lint.readthedocs.io/rules/ - fcqn-builtins - no-log-password - no-same-owner diff --git a/.bandit.yml b/.bandit.yml index 2b618f6..663c521 100644 --- a/.bandit.yml +++ b/.bandit.yml @@ -3,7 +3,7 @@ # https://bandit.readthedocs.io/en/latest/config.html # Tests are first included by `tests`, and then excluded by `skips`. -# If `tests` is empty, all tests are are considered included. +# If `tests` is empty, all tests are considered included. tests: # - B101 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 341582d..56ca480 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,13 @@ --- -version: 2 +# Any ignore directives should be uncommented in downstream projects to disable +# Dependabot updates for the given dependency. Downstream projects will get +# these updates when the pull request(s) in the appropriate skeleton are merged +# and Lineage processes these changes. + updates: - - package-ecosystem: "docker" - directory: "/" + - directory: / + package-ecosystem: docker schedule: interval: "daily" labels: @@ -30,8 +34,8 @@ updates: patterns: - "*" - - package-ecosystem: "pip" - directory: "/" + - directory: / + package-ecosystem: pip schedule: interval: "daily" labels: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 770b23d..2233325 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,9 @@ name: Build on: push: branches: - - '**' + - "**" + tags: + - "v*.*.*" pull_request: release: types: [edited, published] diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ab30f03..f39e169 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -17,7 +17,8 @@ on: branches: [develop] pull_request: # The branches below must be a subset of the branches above - branches: [develop] + branches: + - develop schedule: - cron: '31 7 * * 2' @@ -26,8 +27,27 @@ permissions: contents: read jobs: + diagnostics: + name: Run diagnostics + runs-on: ubuntu-latest + steps: + # Note that a duplicate of this step must be added at the top of + # each job. + - id: harden-runner + name: Harden the runner + uses: step-security/harden-runner@v2 + with: + egress-policy: audit + - id: github-status + name: Check GitHub status + uses: crazy-max/ghaction-github-status@v3 + - id: dump-context + name: Dump context + uses: crazy-max/ghaction-dump-context@v2 analyze: name: Analyze + needs: + - diagnostics runs-on: ubuntu-latest permissions: actions: read @@ -58,9 +78,11 @@ jobs: with: languages: ${{ matrix.language }} + # Autobuild attempts to build any compiled languages (C/C++, C#, or # Autobuild attempts to build any compiled languages (C/C++, C#, or # Java). If this step fails, then you should remove it and run the build # manually (see below). + # manually (see below). - name: Autobuild uses: github/codeql-action/autobuild@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # tag=codeql-bundle-v3.26.5 @@ -70,10 +92,14 @@ jobs: # ✏️ If the Autobuild fails above, remove it and uncomment the following # three lines and modify them (or add more) to build your code if your # project uses a compiled language + # three lines and modify them (or add more) to build your code if your + # project uses a compiled language # - run: | # make bootstrap # make release + # make bootstrap + # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # tag=codeql-bundle-v3.26.5 diff --git a/.mdl_config.yaml b/.mdl_config.yaml index eabf041..79aebe9 100644 --- a/.mdl_config.yaml +++ b/.mdl_config.yaml @@ -45,11 +45,7 @@ MD035: # Enforce dashes for horizontal rules style: "---" -# MD041/first-line-heading -# Allow the first line to be something other than a top-level heading -MD041: false - -# MD046/code-block-style Code block style +# MD046/code-block-style - Code block style MD046: # Enforce the fenced style for code blocks style: "fenced" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5828261..144df31 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,27 +4,34 @@ default_language_version: python: python3 repos: + # Check the pre-commit configuration + - repo: meta + hooks: + - id: check-useless-excludes + - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: check-case-conflict - id: check-executables-have-shebangs - id: check-json - id: check-merge-conflict + - id: check-shebang-scripts-are-executable + - id: check-symlinks - id: check-toml + - id: check-vcs-permalinks - id: check-xml - id: debug-statements + - id: destroyed-symlinks - id: detect-aws-credentials args: - --allow-missing-credentials - id: detect-private-key - id: end-of-file-fixer - exclude: files/(issue|motd) - id: mixed-line-ending args: - --fix=lf - id: pretty-format-json - exclude: package-lock.json args: - --autofix - id: requirements-txt-fixer @@ -32,17 +39,17 @@ repos: # Text file hooks - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.33.0 + rev: v0.42.0 hooks: - id: markdownlint args: - --config=.mdl_config.yaml - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.4 + - repo: https://github.com/rbubley/mirrors-prettier + rev: v3.3.3 hooks: - id: prettier - repo: https://github.com/adrienverge/yamllint - rev: v1.29.0 + rev: v1.35.1 hooks: - id: yamllint args: @@ -50,94 +57,172 @@ repos: # GitHub Actions hooks - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.21.0 + rev: 0.29.4 hooks: - id: check-github-actions - id: check-github-workflows # pre-commit hooks - repo: https://github.com/pre-commit/pre-commit - rev: v3.0.4 + rev: v4.0.1 hooks: - id: validate_manifest + # Go hooks + - repo: https://github.com/TekWizely/pre-commit-golang + rev: v1.0.0-rc.1 + hooks: + # Go Build + - id: go-build-repo-mod + # Style Checkers + - id: go-critic + # goimports + - id: go-imports-repo + args: + # Write changes to files + - -w + # Go Mod Tidy + - id: go-mod-tidy-repo + # GoSec + - id: go-sec-repo-mod + # StaticCheck + - id: go-staticcheck-repo-mod + # Go Test + - id: go-test-repo-mod + # Go Vet + - id: go-vet-repo-mod + # Nix hooks + - repo: https://github.com/nix-community/nixpkgs-fmt + rev: v1.3.0 + hooks: + - id: nixpkgs-fmt + # Shell script hooks - - repo: https://github.com/cisagov/pre-commit-shfmt - rev: v0.0.2 + - repo: https://github.com/scop/pre-commit-shfmt + rev: v3.10.0-1 hooks: - id: shfmt args: + # List files that will be formatted + - --list + # Write result to file instead of stdout + - --write # Indent by two spaces - - -i - - '2' + - --indent + - "2" # Binary operators may start a line - - -bn + - --binary-next-line # Switch cases are indented - - -ci + - --case-indent # Redirect operators are followed by a space - - -sr - - repo: https://github.com/detailyang/pre-commit-shell - rev: 1.0.5 + - --space-redirects + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 hooks: - - id: shell-lint - args: [-x] + - id: shellcheck # Python hooks - # Run bandit on the "tests" tree with a configuration - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.7.10 hooks: - id: bandit - name: bandit (tests tree) - files: tests args: - --config=.bandit.yml - # Run bandit on everything except the "tests" tree - - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 - hooks: - - id: bandit - name: bandit (everything else) - exclude: tests - - repo: https://github.com/psf/black - rev: 23.1.0 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 24.10.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.1.1 hooks: - id: flake8 additional_dependencies: - - flake8-docstrings + - flake8-docstrings==1.7.0 - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.1 + rev: v1.13.0 hooks: - id: mypy + - repo: https://github.com/pypa/pip-audit + rev: v2.7.3 + hooks: + - id: pip-audit + args: + # Add any pip requirements files to scan + - --requirement + - requirements-dev.txt + - --requirement + - requirements-test.txt + - --requirement + - requirements.txt - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.19.0 hooks: - id: pyupgrade # Ansible hooks - - repo: https://github.com/ansible-community/ansible-lint - rev: v6.14.0a0 + - repo: https://github.com/ansible/ansible-lint + rev: v24.10.0 hooks: - id: ansible-lint - # files: molecule/default/playbook.yml + additional_dependencies: + # On its own ansible-lint does not pull in ansible, only + # ansible-core. Therefore, if an Ansible module lives in + # ansible instead of ansible-core, the linter will complain + # that the module is unknown. In these cases it is + # necessary to add the ansible package itself as an + # additional dependency, with the same pinning as is done in + # requirements-test.txt of cisagov/skeleton-ansible-role. + # + # Version 10 is required because the pip-audit pre-commit + # hook identifies a vulnerability in ansible-core 2.16.13, + # but all versions of ansible 9 have a dependency on + # ~=2.16.X. + # + # It is also a good idea to go ahead and upgrade to version + # 10 since version 9 is going EOL at the end of November: + # https://endoflife.date/ansible + # - ansible>=10,<11 + # ansible-core 2.16.3 through 2.16.6 suffer from the bug + # discussed in ansible/ansible#82702, which breaks any + # symlinked files in vars, tasks, etc. for any Ansible role + # installed via ansible-galaxy. Hence we never want to + # install those versions. + # + # Note that the pip-audit pre-commit hook identifies a + # vulnerability in ansible-core 2.16.13. The pin of + # ansible-core to >=2.17 effectively also pins ansible to + # >=10. + # + # It is also a good idea to go ahead and upgrade to + # ansible-core 2.17 since security support for ansible-core + # 2.16 ends this month: + # https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix + # + # Note that any changes made to this dependency must also be + # made in requirements.txt in cisagov/skeleton-packer and + # requirements-test.txt in cisagov/skeleton-ansible-role. + - ansible-core>=2.17 # Terraform hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.77.1 + rev: v1.96.1 hooks: - id: terraform_fmt - id: terraform_validate # Docker hooks - repo: https://github.com/IamTheFij/docker-pre-commit - rev: v2.1.1 + rev: v3.0.1 hooks: - id: docker-compose-check + + # Packer hooks + - repo: https://github.com/cisagov/pre-commit-packer + rev: v0.3.0 + hooks: + - id: packer_fmt + - id: packer_validate diff --git a/Dockerfile b/Dockerfile index d504c51..820d7ba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,13 @@ # syntax=docker/dockerfile:1 -ARG PYTHON_VERSION=3.11.2 +ARG PYTHON_VERSION=3.13.0 ARG WEEWX_UID=421 ARG WEEWX_VERSION=4.10.2 ARG WEEWX_HOME="/home/weewx" FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx -FROM --platform=$BUILDPLATFORM python:${PYTHON_VERSION} as build-stage +FROM --platform=$BUILDPLATFORM python:${PYTHON_VERSION} AS build-stage ARG WEEWX_VERSION ARG ARCHIVE="weewx-${WEEWX_VERSION}.tar.gz" @@ -49,11 +49,11 @@ RUN pip install --no-cache --requirement requirements.txt WORKDIR /root -RUN bin/wee_extension --install /tmp/weewx-mqtt.zip -RUN bin/wee_extension --install /tmp/weewx-interceptor.zip +# RUN bin/wee_extension --install /tmp/weewx-mqtt.zip +# RUN bin/wee_extension --install /tmp/weewx-interceptor.zip COPY src/entrypoint.sh src/_version.py ./ -FROM python:${PYTHON_VERSION}-slim-bullseye as final-stage +FROM python:${PYTHON_VERSION}-slim AS final-stage ARG TARGETPLATFORM ARG WEEWX_HOME @@ -61,10 +61,10 @@ ARG WEEWX_UID # For a list of pre-defined annotation keys and value types see: # https://github.com/opencontainers/image-spec/blob/master/annotations.md +# # Note: Additional labels are added by the build workflow. LABEL org.opencontainers.image.authors="markf+github@geekpad.com" LABEL org.opencontainers.image.vendor="Geekpad" -LABEL com.weewx.version=${WEEWX_VERSION} RUN addgroup --system --gid ${WEEWX_UID} weewx \ && adduser --system --uid ${WEEWX_UID} --ingroup weewx weewx diff --git a/README.md b/README.md index 77b93c6..ebd2135 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ services: background with: ```console - docker compose up -d + docker compose up --detach ``` ## Upgrading ## diff --git a/bump_version.sh b/bump_version.sh index e77206d..858ff4a 100755 --- a/bump_version.sh +++ b/bump_version.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash -# bump_version.sh (show|major|minor|patch|prerelease|build) +# Usage: +# bump_version.sh (show|major|minor|patch|finalize) +# bump_version.sh (build|prerelease) [token] +# Notes: +# - If you specify a token it will only be used if the current version is +# tokenless or if the provided token matches the token used in the current +# version. set -o nounset set -o errexit @@ -9,43 +15,67 @@ set -o pipefail VERSION_FILE=src/_version.py README_FILE=README.md -HELP_INFORMATION="bump_version.sh (show|major|minor|patch|prerelease|build|finalize)" +function usage { + cat << HELP +Usage: + ${0##*/} (show|major|minor|patch|finalize) + ${0##*/} (build|prerelease) [token] -old_version=$(sed -n "s/^__version__ = \"\(.*\)\"$/\1/p" $VERSION_FILE) +Notes: + - If you specify a token it will only be used if the current version is + tokenless or if the provided token matches the token used in the current + version. +HELP + exit 1 +} -if [ $# -ne 1 ]; then - echo "$HELP_INFORMATION" +function update_version { + # Comment out periods so they are interpreted as periods and don't + # just match any character + old_version_regex=${1//\./\\\.} + + echo Changing version from "$1" to "$2" + tmp_file=/tmp/version.$$ + sed "s/$old_version_regex/$2/" $VERSION_FILE > $tmp_file + mv $tmp_file $VERSION_FILE + sed "s/$old_version_regex/$2/" $README_FILE > $tmp_file + mv $tmp_file $README_FILE + git add $VERSION_FILE $README_FILE + git commit --message "$3" +} + +if [ $# -lt 1 ] || [ $# -gt 2 ]; then + usage else + old_version=$(sed -n "s/^__version__ = \"\(.*\)\"$/\1/p" $VERSION_FILE) case $1 in - major | minor | patch | prerelease | build) + major | minor | patch) + if [ $# -ne 1 ]; then + usage + fi new_version=$(python -c "import semver; print(semver.bump_$1('$old_version'))") - echo Changing version from "$old_version" to "$new_version" - tmp_file=/tmp/version.$$ - sed "s/$old_version/$new_version/" $VERSION_FILE > $tmp_file - mv $tmp_file $VERSION_FILE - sed "s/$old_version/$new_version/" $README_FILE > $tmp_file - mv $tmp_file $README_FILE - git add $VERSION_FILE $README_FILE - git commit -m"Bump version from $old_version to $new_version" - git push + update_version "$old_version" "$new_version" "Bump version from $old_version to $new_version" + ;; + build | prerelease) + if [ $# -eq 2 ]; then + new_version=$(python -c "import semver; print(semver.bump_$1('$old_version', token='$2'))") + else + new_version=$(python -c "import semver; print(semver.bump_$1('$old_version'))") + fi + update_version "$old_version" "$new_version" "Bump version from $old_version to $new_version" ;; finalize) + if [ $# -ne 1 ]; then + usage + fi new_version=$(python -c "import semver; print(semver.finalize_version('$old_version'))") - echo Changing version from "$old_version" to "$new_version" - tmp_file=/tmp/version.$$ - sed "s/$old_version/$new_version/" $VERSION_FILE > $tmp_file - mv $tmp_file $VERSION_FILE - sed "s/$old_version/$new_version/" $README_FILE > $tmp_file - mv $tmp_file $README_FILE - git add $VERSION_FILE $README_FILE - git commit -m"Bump version from $old_version to $new_version" - git push + update_version "$old_version" "$new_version" "Finalize version from $old_version to $new_version" ;; show) echo "$old_version" ;; *) - echo "$HELP_INFORMATION" + usage ;; esac fi diff --git a/requirements-test.txt b/requirements-test.txt index a4af5aa..fa5199a 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1 +1,5 @@ --e .[test] +--editable .[test] +--requirement requirements.txt +pre-commit +pytest +python-on-whales diff --git a/requirements.txt b/requirements.txt index d6e1198..1dc64ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ --e . +--editable . diff --git a/setup-env b/setup-env index f526cdb..77926bf 100755 --- a/setup-env +++ b/setup-env @@ -65,7 +65,7 @@ done eval set -- "$PARAMS" # Check to see if pyenv is installed -if [ -z "$(command -v pyenv)" ] || [ -z "$(command -v pyenv-virtualenv)" ]; then +if [ -z "$(command -v pyenv)" ] || { [ -z "$(command -v pyenv-virtualenv)" ] && [ ! -f "$(pyenv root)/plugins/pyenv-virtualenv/bin/pyenv-virtualenv" ]; }; then echo "pyenv and pyenv-virtualenv are required." if [[ "$OSTYPE" == "darwin"* ]]; then cat << 'END_OF_LINE' @@ -186,5 +186,5 @@ else: END_OF_LINE )" -# Qapla +# Qapla' echo "Success!" diff --git a/setup.py b/setup.py index 5f0677e..4ca2ba4 100644 --- a/setup.py +++ b/setup.py @@ -77,12 +77,12 @@ def package_vars(version_file): ], extras_require={ "test": [ - "coverage == 6.5.0", - "coveralls == 4.0.1", - "docker == 7.1.0", - "pre-commit == 4.0.1", - "pytest == 8.3.3", - "pytest-cov == 6.0.0", + "coverage", + "coveralls", + "docker", + "pre-commit", + "pytest", + "pytest-cov", ] }, ) diff --git a/tests/container_test.py b/tests/container_test.py old mode 100644 new mode 100755