From dee6760318f45519e94cb7f80d3a8997c20698ae Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 00:55:31 +0000 Subject: [PATCH 01/12] ci: rework actions configuration and pre-commit hooks --- .github/workflows/cd-docker.yml | 284 ++---------------- .github/workflows/ci-testing.yml | 73 ----- .github/workflows/pr-checks.yml | 37 +++ .github/workflows/prek.yaml | 30 ++ .github/workflows/pytest.yaml | 42 +++ .../{cd-release.yaml => release.yaml} | 56 ++-- .pre-commit-config.yaml | 117 ++++---- .yamllint | 59 ++++ 8 files changed, 284 insertions(+), 414 deletions(-) delete mode 100644 .github/workflows/ci-testing.yml create mode 100644 .github/workflows/pr-checks.yml create mode 100644 .github/workflows/prek.yaml create mode 100644 .github/workflows/pytest.yaml rename .github/workflows/{cd-release.yaml => release.yaml} (74%) create mode 100644 .yamllint diff --git a/.github/workflows/cd-docker.yml b/.github/workflows/cd-docker.yml index 8673fd4..c575d44 100644 --- a/.github/workflows/cd-docker.yml +++ b/.github/workflows/cd-docker.yml @@ -1,277 +1,49 @@ -# This workflow builds a multi-arch Docker image using GitHub Actions and separated Github Runners with native support for ARM64 and AMD64 architectures, without using QEMU emulation. -# It uses Docker Buildx to build and push the image to GitHub Container Registry (GHCR). +# This workflow builds a multi-arch Docker image using GitHub Actions and separated Github Runners +# with native support for ARM64 and AMD64 architectures, without using QEMU emulation. name: CD Build and publish multi arch Docker Image +permissions: {} +# yamllint disable-line rule:truthy on: workflow_dispatch: push: + branches: + - "main" tags: - - 'v*.*.*' + - "v*" + pull_request: env: # The name of the Docker image to be built and pushed to GHCR - # The image name is derived from the GitHub repository name and the GitHub Container Registry (GHCR) URL. - # The image name will be in the format: ghcr.io// GHCR_IMAGE: ghcr.io/${{ github.repository }} -permissions: - # Global permissions for the workflow, which can be overridden at the job level - contents: read - concurrency: - # This concurrency group ensures that only one job in the group runs at a time. - # If a new job is triggered, the previous one will be canceled. group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: - # The build job builds the Docker image for each platform specified in the matrix. build: - strategy: - fail-fast: false - matrix: - include: - - platform: linux/amd64 - platform_pair: linux-amd64 - - platform: linux/arm64 - platform_pair: linux-arm64 - # The matrix includes two platforms: linux/amd64 and linux/arm64. - # The build job will run for each platform in the matrix. - + uses: docker/github-builder/.github/workflows/build.yml@7d2a02426d4b989616ba5aaee4e879afd4134b0d # v1.6.0 permissions: - # Permissions for the build job, which can be overridden at the step level - # The permissions are set to allow the job to write to the GitHub Container Registry (GHCR) and read from the repository. - attestations: write - actions: read - checks: write - contents: write - deployments: none - id-token: write - issues: read - discussions: read - packages: write - pages: none - pull-requests: read - repository-projects: read - security-events: read - statuses: read - - runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-latest' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }} - # The job runs on different runners based on the platform. - # For linux/amd64, it runs on the latest Ubuntu runner. - # For linux/arm64, it runs on an Ubuntu 24.04 ARM runner. - # The runner is selected based on the platform specified in the matrix. - - name: Build Docker image for ${{ matrix.platform }} - - steps: - - - name: Prepare environment for current platform - # This step sets up the environment for the current platform being built. - # It replaces the '/' character in the platform name with '-' and sets it as an environment variable. - # This is useful for naming artifacts and other resources that cannot contain '/'. - # The environment variable PLATFORMS_PAIR will be used later in the workflow. - id: prepare - run: | - platform=${{ matrix.platform }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - - - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - # This step checks out the code from the repository. - # It uses the actions/checkout action to clone the repository into the runner's workspace. - - - name: Docker meta default - # This step generates metadata for the Docker image. - # It uses the docker/metadata-action to create metadata based on the repository information. - # The metadata includes information such as the image name, tags, and labels. - # The metadata will be used later in the workflow to build and push the Docker image. - id: meta - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 - with: - images: ${{ env.GHCR_IMAGE }} - - - name: Set up Docker Context for Buildx - # This step sets up a Docker context for Buildx. - # It creates a new context named "builders" that will be used for building the Docker image. - # The context allows Buildx to use the Docker daemon for building images. - id: buildx-context - run: | - docker context create builders - - - name: Set up Docker Buildx - # This step sets up Docker Buildx, which is a Docker CLI plugin for extended build capabilities with BuildKit. - # It uses the docker/setup-buildx-action to configure Buildx with the specified context and platforms. - # The platforms are specified in the matrix and will be used for building the Docker image. - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - with: - endpoint: builders - platforms: ${{ matrix.platform }} - - - name: Login to GitHub Container Registry - # This step logs in to the GitHub Container Registry (GHCR) using the docker/login-action. - # It uses the GitHub actor's username and the GITHUB_TOKEN secret for authentication. - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 - with: - registry: ghcr.io + contents: read # to fetch the repository content + id-token: write # for signing attestation(s) with GitHub OIDC Token + packages: write # to push the built image to GitHub Container Registry + with: + output: image + push: ${{ github.event_name != 'pull_request' }} + platforms: linux/amd64,linux/arm64 + build-args: | + VERSION=${{ meta.version }} + cache: true + cache-scope: pyomnilogic-local-docker-cache + meta-images: ghcr.io/cryptk/python-omnilogic-local + meta-tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + secrets: + registry-auths: | + - registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - - - name: Build and push by digest - # This step builds and pushes the Docker image using Buildx. - # It uses the docker/build-push-action to build the image with the specified context and platforms. - # The image is built with the labels and annotations generated in the previous steps. - # The outputs are configured to push the image by digest, which allows for better caching and versioning. - # The cache-from and cache-to options are used to enable caching for the build process. - # The cache is stored in GitHub Actions cache and is scoped to the repository, branch, and platform. - id: build - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - env: - DOCKER_BUILDKIT: 1 - with: - context: . - build-args: | - VERSION=${{ steps.meta.outputs.version }} - platforms: ${{ matrix.platform }} - labels: ${{ steps.meta.outputs.labels }} - annotations: ${{ steps.meta.outputs.annotations }} - outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true,oci-mediatypes=true - cache-from: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }} - cache-to: type=gha,scope=${{ github.repository }}-${{ github.ref_name }}-${{ matrix.platform }} - - - - name: Export digest - # This step exports the digest of the built image to a file. - # It creates a directory in /tmp/digests and saves the digest of the image to a file. - # The digest is obtained from the output of the build step. - # The digest is used to uniquely identify the built image and can be used for further processing or verification. - run: | - mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" - - - name: Upload digest - # This step uploads the digest file to the GitHub Actions artifact storage. - # It uses the actions/upload-artifact action to upload the file created in the previous step. - # The artifact is named digests-${{ matrix.platform_pair }}, where platform_pair is the platform name with '/' replaced by '-'. - # The artifact is retained for 1 day, and if no files are found, it will throw an error. - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: digests-${{ matrix.platform_pair }} - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 - - - merge: - # This job merges the Docker manifests for the different platforms built in the previous job. - name: Merge Docker manifests - runs-on: ubuntu-latest - permissions: - attestations: write - actions: read - checks: read - contents: read - deployments: none - id-token: write - issues: read - discussions: read - packages: write - pages: none - pull-requests: read - repository-projects: read - security-events: read - statuses: read - - needs: - - build - # This job depends on the build job to complete before it starts. - # It ensures that the Docker images for all platforms are built before merging the manifests. - steps: - - name: Download digests - # This step downloads the digest files uploaded in the build job. - # It uses the actions/download-artifact action to download the artifacts with the pattern digests-*. - # The downloaded files are merged into the /tmp/digests directory. - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 - with: - path: /tmp/digests - pattern: digests-* - merge-multiple: true - - - - name: Docker meta - # This step generates metadata for the Docker image. - # It uses the docker/metadata-action to create metadata based on the repository information. - # The metadata includes information such as the image name, tags, and labels. - id: meta - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 - with: - images: ${{ env.GHCR_IMAGE }} - annotations: | - type=org.opencontainers.image.description,value=${{ github.event.repository.description || 'No description provided' }} - tags: | - type=ref,event=tag - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - # This step sets up Docker Buildx, which is a Docker CLI plugin for extended build capabilities with BuildKit. - with: - driver-opts: | - network=host - - - name: Login to GitHub Container Registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 - # This step logs in to the GitHub Container Registry (GHCR) using the docker/login-action. - # It uses the GitHub actor's username and the GITHUB_TOKEN secret for authentication. - # The login is necessary to push the merged manifest list to GHCR. - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Get execution timestamp with RFC3339 format - # This step gets the current execution timestamp in RFC3339 format. - # It uses the date command to get the current UTC time and formats it as a string. - # The timestamp is used for annotating the Docker manifest list. - id: timestamp - run: | - echo "timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT - - - name: Create manifest list and pushs - # This step creates a manifest list for the Docker images built for different platforms. - # It uses the docker buildx imagetools create command to create the manifest list. - # The manifest list is annotated with metadata such as description, creation timestamp, and source URL. - # The annotations are obtained from the metadata generated in the previous steps. - # The manifest list is pushed to the GitHub Container Registry (GHCR) with the specified tags. - working-directory: /tmp/digests - id: manifest-annotate - continue-on-error: true - run: | - docker buildx imagetools create \ - $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - --annotation='index:org.opencontainers.image.description=${{ github.event.repository.description }}' \ - --annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \ - --annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \ - --annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \ - $(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *) - - - name: Create manifest list and push without annotations - # This step creates a manifest list for the Docker images built for different platforms. - # It uses the docker buildx imagetools create command to create the manifest list. - # The manifest list is created without annotations if the previous step fails. - # The manifest list is pushed to the GitHub Container Registry (GHCR) with the specified tags. - if: steps.manifest-annotate.outcome == 'failure' - working-directory: /tmp/digests - run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *) - - - name: Inspect image - # This step inspects the created manifest list to verify its contents. - # It uses the docker buildx imagetools inspect command to display information about the manifest list. - # The inspection output will show the platforms and tags associated with the manifest list. - id: inspect - run: | - docker buildx imagetools inspect '${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}' diff --git a/.github/workflows/ci-testing.yml b/.github/workflows/ci-testing.yml deleted file mode 100644 index 0739f20..0000000 --- a/.github/workflows/ci-testing.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: CI Testing Workflow - -on: - workflow_dispatch: - pull_request: - branches: - - main - push: - branches: - - main - tags-ignore: - - '**' - -concurrency: - group: ${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - # Make sure commit messages follow the conventional commits convention: - # https://www.conventionalcommits.org - commitlint: - name: Lint Commit Messages - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: wagoid/commitlint-github-action@v5.3.0 - - prek: - name: Run prek checks - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Check out code from GitHub - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - with: - persist-credentials: false - - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 #6.2.0 - - name: Install the latest version of uv - uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 - - name: Run prek - uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 #v2.0.2 - - test: - strategy: - fail-fast: false - matrix: - python-version: - - "3.14" - os: - - ubuntu-latest - - windows-latest - - macOS-latest - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - name: Install uv - uses: astral-sh/setup-uv@v5 - with: - enable-cache: true - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install Dependencies - run: uv sync --all-extras - shell: bash - - name: Test with Pytest - run: uv run pytest - shell: bash diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 0000000..092f42e --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,37 @@ +name: CI Testing Workflow + +permissions: {} + +# yamllint disable-line rule:truthy +on: + workflow_dispatch: + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + # Make sure commit messages follow the conventional commits convention: + # https://www.conventionalcommits.org + commitlint: + name: Lint Commit Messages + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + fetch-depth: 0 + - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1 + + prek: + name: Run Prek Checks + uses: ./.github/workflows/prek.yml + + test: + name: Run Pytest Suite + uses: ./.github/workflows/pytest.yml diff --git a/.github/workflows/prek.yaml b/.github/workflows/prek.yaml new file mode 100644 index 0000000..731f2e1 --- /dev/null +++ b/.github/workflows/prek.yaml @@ -0,0 +1,30 @@ +name: Run Prek Checks + +permissions: {} + +# yamllint disable-line rule:truthy +on: + workflow_dispatch: + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + prek: + name: Run prek checks + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check out code from GitHub + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # 6.2.0 + - name: Install the latest version of uv + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 + - name: Run prek + uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2 diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml new file mode 100644 index 0000000..701d27f --- /dev/null +++ b/.github/workflows/pytest.yaml @@ -0,0 +1,42 @@ +name: Run Pytest Suite + +permissions: {} + +# yamllint disable-line rule:truthy +on: + workflow_dispatch: + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Run Pytest Suite + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - windows-latest + - macOS-latest + runs-on: ${{ matrix.os }} + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Install uv + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + enable-cache: ${{ github.event_name != 'pull_request' }} + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # 6.2.0 + - name: Install Dependencies + run: uv sync --all-extras + shell: bash + - name: Test with Pytest + run: uv run pytest + shell: bash diff --git a/.github/workflows/cd-release.yaml b/.github/workflows/release.yaml similarity index 74% rename from .github/workflows/cd-release.yaml rename to .github/workflows/release.yaml index a3fc45d..a0f9d32 100644 --- a/.github/workflows/cd-release.yaml +++ b/.github/workflows/release.yaml @@ -1,32 +1,38 @@ name: CD Release and Publish +permissions: {} + +# yamllint disable-line rule:truthy on: - workflow_run: - workflows: - - CI Testing Workflow - types: - - completed - branches: - - main + # We don't need to release a new version with every commit to main + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: - check_success: - runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.conclusion == 'success' }} - steps: - - name: Workflow completed successfully - run: echo "CI workflow passed. Proceeding with CD." + test: + name: Run Pytest Suite + uses: ./.github/workflows/pytest.yml + + prek: + name: Run Prek Checks + uses: ./.github/workflows/prek.yml release: + name: Create Release and Publish runs-on: ubuntu-latest - needs: check_success + needs: + - test + - prek concurrency: group: ${{ github.workflow }}-release-${{ github.ref_name }} cancel-in-progress: false environment: release permissions: - contents: write + contents: write # Required to allow creating releases and uploading release assets outputs: released: ${{ steps.release.outputs.released }} @@ -39,15 +45,18 @@ jobs: # possible that the branch was updated while the workflow was running. This # prevents accidentally releasing un-evaluated changes. - name: Setup | Checkout Repository on Release Branch - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: + persist-credentials: false token: ${{ secrets.PYTHON_SEMANTIC_RELEASE_TOKEN }} ref: ${{ github.ref_name }} fetch-depth: 0 - name: Setup | Force release branch to be at workflow sha run: | - git reset --hard ${{ github.sha }} + git reset --hard "${GITHUB_SHA}" + env: + GITHUB_SHA: ${{ github.sha }} - name: Evaluate | Verify upstream has NOT changed # Last chance to abort before causing an error as another PR/push was applied to @@ -91,21 +100,21 @@ jobs: - name: Action | Semantic Version Release id: release # Adjust tag with desired version if applicable. - uses: python-semantic-release/python-semantic-release@v10.5.3 + uses: python-semantic-release/python-semantic-release@350c48fcb3ffcdfd2e0a235206bc2ecea6b69df0 # v10.5.3 with: github_token: ${{ secrets.GITHUB_TOKEN }} git_committer_name: "github-actions" git_committer_email: "actions@users.noreply.github.com" - name: Publish | Upload to GitHub Release Assets - uses: python-semantic-release/publish-action@v10.4.1 + uses: python-semantic-release/publish-action@350c48fcb3ffcdfd2e0a235206bc2ecea6b69df0 # v10.5.3 if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ steps.release.outputs.tag }} - name: Upload | Distribution Artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: steps.release.outputs.released == 'true' with: name: distribution-artifacts @@ -117,6 +126,7 @@ jobs: # the least amount of token privilege # 2. Also, deployments can fail, and its better to have a separate job if you need to retry # and it won't require reversing the release. + name: Upload release to PyPI runs-on: ubuntu-latest needs: release if: ${{ needs.release.outputs.released == 'true' }} @@ -124,18 +134,18 @@ jobs: environment: release permissions: contents: read - id-token: write + id-token: write # Required for pypi for trusted publishing steps: - name: Setup | Download Build Artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 id: artifact-download with: name: distribution-artifacts path: dist - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 with: packages-dir: dist print-hash: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 97b5900..24ed03a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,67 +1,60 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks exclude: "CHANGELOG.md" -default_stages: [ pre-commit ] +default_stages: [pre-commit] repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: debug-statements - - id: check-builtin-literals - - id: check-case-conflict - - id: check-docstring-first - - id: check-json - exclude: ^.vscode/ - - id: check-toml - - id: detect-private-key - - id: end-of-file-fixer - - id: trailing-whitespace - - repo: https://github.com/astral-sh/uv-pre-commit - # uv version. - rev: 0.9.8 - hooks: - - id: uv-lock - - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 - hooks: - - id: codespell - exclude: uv.lock - - repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version - rev: v0.14.4 - hooks: - # Run the linter - - id: ruff-check - args: [ --fix ] - # Run the formatter - - id: ruff-format - # - repo: https://github.com/PyCQA/isort # Replacing isort with ruff - # rev: 7.0.0 - # hooks: - # - id: isort - # - repo: https://github.com/psf/black # Replacing black with ruff - # rev: 25.9.0 - # hooks: - # - id: black - # - repo: local # Replacing pylint with ruff - # hooks: - # - id: pylint - # name: pylint - # entry: uv run pylint - # language: system - # types: [python] - # require_serial: true - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.20.1 - hooks: - - id: mypy - exclude: cli.py - additional_dependencies: - - "pydantic>=2.0.0" - - "pytest>=8.0.0" - - "types-xmltodict >=1.0.1,<2.0.0" - - "click >=8.0.0,<9.0.0" - - "scapy>=2.6.1,<3.0.0" - args: [ "--config-file=./pyproject.toml"] - files: ^pyomnilogic_local/.+\.(py|pyi)$ + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version + rev: v0.15.10 + hooks: + # Run the linter + - id: ruff-check + types_or: [python, pyi] + args: [--fix] + # Run the formatter + - id: ruff-format + types_or: [python, pyi] + - repo: https://github.com/codespell-project/codespell + rev: v2.4.2 + hooks: + - id: codespell + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: v1.24.1 + hooks: + - id: zizmor + args: + - --pedantic + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-json + exclude: ^.vscode/ + - id: check-toml + - id: no-commit-to-branch + args: + - --branch=main + - --branch=dev + - id: debug-statements + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.38.0 + hooks: + - id: yamllint + - repo: https://github.com/astral-sh/uv-pre-commit + # uv version. + rev: 0.11.6 + hooks: + - id: uv-lock + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.20.1 + hooks: + - id: mypy + # exclude: cli.py + additional_dependencies: + - "pydantic>=2.0.0" + - "pytest>=8.0.0" + - "types-xmltodict >=1.0.1,<2.0.0" + - "click >=8.0.0,<9.0.0" + - "scapy>=2.6.1,<3.0.0" + args: ["--config-file=./pyproject.toml"] + files: ^pyomnilogic_local/.+\.(py|pyi)$ diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..0148408 --- /dev/null +++ b/.yamllint @@ -0,0 +1,59 @@ +rules: + braces: + level: error + min-spaces-inside: 0 + max-spaces-inside: 1 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + brackets: + level: error + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + colons: + level: error + max-spaces-before: 0 + max-spaces-after: 1 + commas: + level: error + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + comments: + level: error + require-starting-space: true + min-spaces-from-content: 1 + comments-indentation: + level: error + document-end: + level: error + present: false + document-start: + level: error + present: false + empty-lines: + level: error + max: 1 + max-start: 0 + max-end: 1 + hyphens: + level: error + max-spaces-after: 1 + indentation: + level: error + spaces: 2 + indent-sequences: true + check-multi-line-strings: false + key-duplicates: + level: error + line-length: disable + new-line-at-end-of-file: + level: error + new-lines: + level: error + type: unix + trailing-spaces: + level: error + truthy: + level: error From ca19d38512da433d7af35ccb68a2afdc6254715f Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:31:06 +0000 Subject: [PATCH 02/12] ci: fix incorrect variable syntax in cd-docker.yaml --- .github/workflows/cd-docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd-docker.yml b/.github/workflows/cd-docker.yml index c575d44..a77fe37 100644 --- a/.github/workflows/cd-docker.yml +++ b/.github/workflows/cd-docker.yml @@ -34,7 +34,7 @@ jobs: push: ${{ github.event_name != 'pull_request' }} platforms: linux/amd64,linux/arm64 build-args: | - VERSION=${{ meta.version }} + VERSION={{ meta.version }} cache: true cache-scope: pyomnilogic-local-docker-cache meta-images: ghcr.io/cryptk/python-omnilogic-local From 92112fcbe2618785149be819c607da2a076517ff Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:31:26 +0000 Subject: [PATCH 03/12] ci: rename cd-docker.yaml to docker.yaml --- .github/workflows/{cd-docker.yml => docker.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{cd-docker.yml => docker.yml} (100%) diff --git a/.github/workflows/cd-docker.yml b/.github/workflows/docker.yml similarity index 100% rename from .github/workflows/cd-docker.yml rename to .github/workflows/docker.yml From 681358862d463ff774e77e60f602dda64a94de43 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:33:44 +0000 Subject: [PATCH 04/12] ci: fix reusable workflow calls --- .github/workflows/pr-checks.yml | 4 ++-- .github/workflows/release.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 092f42e..54495e8 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -30,8 +30,8 @@ jobs: prek: name: Run Prek Checks - uses: ./.github/workflows/prek.yml + uses: ./.github/workflows/prek.yaml test: name: Run Pytest Suite - uses: ./.github/workflows/pytest.yml + uses: ./.github/workflows/pytest.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a0f9d32..e0ed54c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,11 +14,11 @@ concurrency: jobs: test: name: Run Pytest Suite - uses: ./.github/workflows/pytest.yml + uses: ./.github/workflows/pytest.yaml prek: name: Run Prek Checks - uses: ./.github/workflows/prek.yml + uses: ./.github/workflows/prek.yaml release: name: Create Release and Publish From a6a1a3a7404917a0a96fb65067a6ce8393ce74b2 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:40:03 +0000 Subject: [PATCH 05/12] ci: dynamically name runs for docker workflow --- .github/workflows/docker.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a77fe37..ec2e767 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,6 +1,7 @@ # This workflow builds a multi-arch Docker image using GitHub Actions and separated Github Runners # with native support for ARM64 and AMD64 architectures, without using QEMU emulation. -name: CD Build and publish multi arch Docker Image +name: Docker Build +run-name: Docker Build${{ github.event_name != 'pull_request' && ' and Publish' || '' }} permissions: {} From 503eb7efb782e4df8d0dcc7fb6c09d58c444d697 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:42:17 +0000 Subject: [PATCH 06/12] ci: fix permissions for reusable workflows --- .github/workflows/pr-checks.yml | 4 ++++ .github/workflows/release.yaml | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 54495e8..a2c824c 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -31,7 +31,11 @@ jobs: prek: name: Run Prek Checks uses: ./.github/workflows/prek.yaml + permissions: + contents: read test: name: Run Pytest Suite uses: ./.github/workflows/pytest.yaml + permissions: + contents: read diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e0ed54c..9ceb829 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -12,13 +12,17 @@ concurrency: cancel-in-progress: true jobs: - test: - name: Run Pytest Suite - uses: ./.github/workflows/pytest.yaml - prek: name: Run Prek Checks uses: ./.github/workflows/prek.yaml + permissions: + contents: read + + test: + name: Run Pytest Suite + uses: ./.github/workflows/pytest.yaml + permissions: + contents: read release: name: Create Release and Publish From 3c8d0392e4670630d24531723092c66d38ad570b Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:48:07 +0000 Subject: [PATCH 07/12] ci: remove concurrency groups from reusable workflows --- .github/workflows/pr-checks.yml | 2 +- .github/workflows/prek.yaml | 5 ----- .github/workflows/pytest.yaml | 5 ----- .github/workflows/release.yaml | 2 +- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index a2c824c..be1ddd1 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -1,4 +1,4 @@ -name: CI Testing Workflow +name: PR Checks permissions: {} diff --git a/.github/workflows/prek.yaml b/.github/workflows/prek.yaml index 731f2e1..0479e47 100644 --- a/.github/workflows/prek.yaml +++ b/.github/workflows/prek.yaml @@ -4,13 +4,8 @@ permissions: {} # yamllint disable-line rule:truthy on: - workflow_dispatch: workflow_call: -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - jobs: prek: name: Run prek checks diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml index 701d27f..7adea1c 100644 --- a/.github/workflows/pytest.yaml +++ b/.github/workflows/pytest.yaml @@ -4,13 +4,8 @@ permissions: {} # yamllint disable-line rule:truthy on: - workflow_dispatch: workflow_call: -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - jobs: test: name: Run Pytest Suite diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9ceb829..202d3c0 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -name: CD Release and Publish +name: Release and Publish permissions: {} From fa500139658932151e48946d9540b061835ed41e Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:49:44 +0000 Subject: [PATCH 08/12] ci: remove names from reusable workflows to clean up UI --- .github/workflows/pr-checks.yml | 2 -- .github/workflows/release.yaml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index be1ddd1..6d43137 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -29,13 +29,11 @@ jobs: - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1 prek: - name: Run Prek Checks uses: ./.github/workflows/prek.yaml permissions: contents: read test: - name: Run Pytest Suite uses: ./.github/workflows/pytest.yaml permissions: contents: read diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 202d3c0..5386c1d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,13 +13,11 @@ concurrency: jobs: prek: - name: Run Prek Checks uses: ./.github/workflows/prek.yaml permissions: contents: read test: - name: Run Pytest Suite uses: ./.github/workflows/pytest.yaml permissions: contents: read From 402ed88ca1fac0b70d278b91e77059798e0d6e12 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:54:51 +0000 Subject: [PATCH 09/12] ci: re-structure actions tests --- .github/workflows/docker.yml | 6 ++++++ .github/workflows/pr-checks.yml | 7 +------ .github/workflows/prek.yaml | 25 ---------------------- .github/workflows/pytest.yaml | 37 --------------------------------- .github/workflows/release.yaml | 8 +------ 5 files changed, 8 insertions(+), 75 deletions(-) delete mode 100644 .github/workflows/prek.yaml delete mode 100644 .github/workflows/pytest.yaml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ec2e767..4893678 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -24,7 +24,13 @@ concurrency: cancel-in-progress: true jobs: + test: + uses: ./.github/workflows/test.yaml + permissions: + contents: read + build: + needs: test uses: docker/github-builder/.github/workflows/build.yml@7d2a02426d4b989616ba5aaee4e879afd4134b0d # v1.6.0 permissions: contents: read # to fetch the repository content diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 6d43137..108da98 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -28,12 +28,7 @@ jobs: fetch-depth: 0 - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1 - prek: - uses: ./.github/workflows/prek.yaml - permissions: - contents: read - test: - uses: ./.github/workflows/pytest.yaml + uses: ./.github/workflows/test.yaml permissions: contents: read diff --git a/.github/workflows/prek.yaml b/.github/workflows/prek.yaml deleted file mode 100644 index 0479e47..0000000 --- a/.github/workflows/prek.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Run Prek Checks - -permissions: {} - -# yamllint disable-line rule:truthy -on: - workflow_call: - -jobs: - prek: - name: Run prek checks - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Check out code from GitHub - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # 6.2.0 - - name: Install the latest version of uv - uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 - - name: Run prek - uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2 diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml deleted file mode 100644 index 7adea1c..0000000 --- a/.github/workflows/pytest.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Run Pytest Suite - -permissions: {} - -# yamllint disable-line rule:truthy -on: - workflow_call: - -jobs: - test: - name: Run Pytest Suite - strategy: - fail-fast: false - matrix: - os: - - ubuntu-latest - - windows-latest - - macOS-latest - runs-on: ${{ matrix.os }} - permissions: - contents: read - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 - with: - enable-cache: ${{ github.event_name != 'pull_request' }} - - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # 6.2.0 - - name: Install Dependencies - run: uv sync --all-extras - shell: bash - - name: Test with Pytest - run: uv run pytest - shell: bash diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5386c1d..4e512b4 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -12,13 +12,8 @@ concurrency: cancel-in-progress: true jobs: - prek: - uses: ./.github/workflows/prek.yaml - permissions: - contents: read - test: - uses: ./.github/workflows/pytest.yaml + uses: ./.github/workflows/test.yaml permissions: contents: read @@ -27,7 +22,6 @@ jobs: runs-on: ubuntu-latest needs: - test - - prek concurrency: group: ${{ github.workflow }}-release-${{ github.ref_name }} cancel-in-progress: false From 4b9ebe01f486829334baae1257b41d4ac7bfef58 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:55:21 +0000 Subject: [PATCH 10/12] ci: add missing test.yaml --- .github/workflows/test.yaml | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/test.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..14273ea --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,54 @@ +name: Run Test Suites + +permissions: {} + +# yamllint disable-line rule:truthy +on: + workflow_call: + +jobs: + prek: + name: Prek + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Check out code from GitHub + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # 6.2.0 + - name: Install the latest version of uv + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 + - name: Run prek + uses: j178/prek-action@cbc2f23eb5539cf20d82d1aabd0d0ecbcc56f4e3 # v2.0.2 + + pytest: + name: Pytest + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - windows-latest + - macOS-latest + runs-on: ${{ matrix.os }} + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Install uv + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + enable-cache: ${{ github.event_name != 'pull_request' }} + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # 6.2.0 + - name: Install Dependencies + run: uv sync --all-extras + shell: bash + - name: Test with Pytest + run: uv run pytest + shell: bash From 2c24e6c3535ba2217b10117d335d7814874d9069 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:57:42 +0000 Subject: [PATCH 11/12] ci: standardize actons file extensions --- .github/workflows/{docker.yml => docker.yaml} | 0 .github/workflows/{pr-checks.yml => pr-checks.yaml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{docker.yml => docker.yaml} (100%) rename .github/workflows/{pr-checks.yml => pr-checks.yaml} (100%) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yaml similarity index 100% rename from .github/workflows/docker.yml rename to .github/workflows/docker.yaml diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yaml similarity index 100% rename from .github/workflows/pr-checks.yml rename to .github/workflows/pr-checks.yaml From b7485aee18b6d04b714bd2c078bf69a587825895 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Thu, 23 Apr 2026 02:00:29 +0000 Subject: [PATCH 12/12] ci: don't run tests as part of docker.yaml if it's a PR check --- .github/workflows/docker.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 4893678..7b20fcd 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -25,12 +25,14 @@ concurrency: jobs: test: + if: github.event_name != 'pull_request' uses: ./.github/workflows/test.yaml permissions: contents: read build: needs: test + if: always() && (needs.test.result == 'success' || needs.test.result == 'skipped') uses: docker/github-builder/.github/workflows/build.yml@7d2a02426d4b989616ba5aaee4e879afd4134b0d # v1.6.0 permissions: contents: read # to fetch the repository content