Skip to content

Build of 104/merge by dependabot[bot] #230

Build of 104/merge by dependabot[bot]

Build of 104/merge by dependabot[bot] #230

Workflow file for this run

# SPDX-License-Identifier: Apache-2.0
# Copyright 2025 Latchfield Technologies http://latchfield.com
name: CI Build
run-name: Build of ${{ github.ref_name }} by ${{ github.actor }}
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
workflow_call:
inputs:
skip_cache:
description: "Skip Commit SHA Cache"
type: boolean
workflow_dispatch:
inputs:
skip_cache:
description: "Skip Commit SHA Cache"
type: boolean
concurrency:
group: build-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'push' || github.event.action == 'pull_request' }}
jobs:
prebuild:
name: Prebuild Checks
runs-on: ubuntu-24.04
if: ${{ github.event_name != 'pull_request' || (!startsWith(github.head_ref, 'dependabot/devcontainers/') && !startsWith(github.head_ref, 'dependabot/docker/')) }}
concurrency:
group: prebuild-${{ github.sha }}
outputs:
tests-cache-hit: ${{ steps.tests.outputs.cache-hit && !inputs.skip_cache }}
security-cache-hit: ${{ steps.security.outputs.cache-hit && !inputs.skip_cache }}
analysis-cache-hit: ${{ steps.analysis.outputs.cache-hit && !inputs.skip_cache }}
build-cache-hit: ${{ steps.build.outputs.cache-hit && !inputs.skip_cache }}
py_vers_current: ${{ steps.config.outputs.py_vers_current }}
py_vers_lesser: ${{ steps.config.outputs.py_vers_lesser }}
py_vers_min: ${{ steps.config.outputs.py_vers_min }}
py_vers_max: ${{ steps.config.outputs.py_vers_max }}
steps:
- name: Lookup test result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: tests
with:
lookup-only: true
path: ./reports/tests/*
key: tests-${{ github.sha }}
- name: Lookup security scan result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: security
with:
lookup-only: true
path: ./reports/security/*
key: security-${{ github.sha }}
- name: Lookup static analysis result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: analysis
with:
lookup-only: true
path: ./reports/analysis/*
key: analysis-${{ github.sha }}
- name: Lookup build cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: build
with:
lookup-only: true
path: |
./dist
key: build-${{ github.sha }}
- name: Evaluate cache status
id: cache
run: |
if [[ "${{ steps.tests.outputs.cache-hit }}" == "true" ]]; then
echo "::notice::Skipping testing job due to cached test report for this commit."
fi
if [[ "${{ steps.security.outputs.cache-hit }}" == "true" ]]; then
echo "::notice::Skipping security check job due to cached security report for this commit."
fi
if [[ "${{ steps.analysis.outputs.cache-hit }}" == "true" ]]; then
echo "::notice::Skipping static analysis job due to cached analysis report for this commit."
fi
if [[ "${{ steps.build.outputs.cache-hit }}" == "true" ]]; then
echo "::notice::Skipping build job due to cached build result for this commit."
fi
echo "fully_cached=${{ steps.tests.outputs.cache-hit && steps.security.outputs.cache-hit && steps.analysis.outputs.cache-hit }}" >> $GITHUB_OUTPUT
- name: Checkout essential prebuild files
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
# Cache warmup for parallel dependent jobs
- name: Prepare the Python environment
if: ${{ !steps.cache.outputs.fully_cached || inputs.skip_cache }}
uses: ./.github/actions/prepare
with:
skip_cache_restore: true
# Get configuration info, this step must not depend on anything from the prepare action
- name: Get configuration info
id: config
shell: bash
run: |
# Resolve the Python versions supported by the project:
python3 utils/pyvers.py >> $GITHUB_OUTPUT
compatibility:
name: Compatibility Tests on Python ${{ matrix.python_version }}
runs-on: ubuntu-24.04
needs: prebuild
concurrency:
group: compatibility-${{ matrix.python_version }}-${{ github.sha }}
env:
CI: true
strategy:
# max-parallel: 1
matrix:
python_version: ${{ fromJSON(needs.prebuild.outputs.py_vers_lesser) }}
include:
- python_version: ${{ needs.prebuild.outputs.py_vers_min }}-lowest_deps
steps:
- name: Fetch compatibility result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: compat
with:
lookup-only: true
path: ./reports/compatibility/${{ matrix.python_version }}
key: compatibility-${{ matrix.python_version }}-${{ github.sha }}
- name: Report on cache
if: ${{ steps.compat.outputs.cache-hit == 'true' && !inputs.skip_cache }}
run: |
echo "::notice::Skipping compatibility test for Python ${{ matrix.python_version }} due to cached result for this commit."
- name: Checkout codebase
if: ${{ steps.compat.outputs.cache-hit != 'true' || inputs.skip_cache }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Run compatibility test
if: ${{ steps.compat.outputs.cache-hit != 'true' || inputs.skip_cache }}
uses: ./.github/actions/tests
with:
python_version: ${{ matrix.python_version }}
full: false
- name: Save compatibility result cache
if: ${{ steps.compat.outputs.cache-hit != 'true' || inputs.skip_cache }}
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: ./reports/compatibility/${{ matrix.python_version }}
key: compatibility-${{ matrix.python_version }}-${{ github.sha }}
tests:
name: Functional Tests on Python ${{ needs.prebuild.outputs.py_vers_max }}
runs-on: ubuntu-24.04
needs: prebuild
if: ${{ needs.prebuild.outputs.tests-cache-hit != 'true' }}
concurrency:
group: tests-${{ github.sha }}
env:
CI: true
steps:
- name: Fetch test result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: tests
with:
path: ./reports/tests/*
key: tests-${{ github.sha }}
- name: Report on cache
if: ${{ steps.tests.outputs.cache-hit }}
run: |
echo "::notice::Skipping testing steps due to cached test report for this commit."
- name: Checkout codebase
if: ${{ !steps.tests.outputs.cache-hit }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Run the tests
if: ${{ !steps.tests.outputs.cache-hit }}
uses: ./.github/actions/tests
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
with:
python_version: ${{ needs.prebuild.outputs.py_vers_max }}
full: true
security:
name: Security Checks
runs-on: ubuntu-24.04
needs: prebuild
if: ${{ needs.prebuild.outputs.security-cache-hit != 'true' }}
concurrency:
group: security-${{ github.sha }}
steps:
- name: Fetch security scan result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: security
with:
path: ./reports/security/*
key: security-${{ github.sha }}
- name: Report on cache
if: ${{ steps.security.outputs.cache-hit }}
run: |
echo "::notice::Skipping security check steps due to cached security report for this commit."
- name: Checkout codebase
if: ${{ !steps.security.outputs.cache-hit }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Prepare the Python environment
if: ${{ !steps.security.outputs.cache-hit }}
uses: ./.github/actions/prepare
- name: Check for outdated project dependencies
if: ${{ !steps.security.outputs.cache-hit }}
run: uv tree -d 1 --outdated --no-dev | grep -e "^├.*latest.*" || true | tee ./reports/security/outdated-dependencies.txt | awk 'NF {print "::warning title=Outdated Dependency::" $0}'
shell: bash
- name: Check for outdated dev/test dependencies
if: ${{ !steps.security.outputs.cache-hit }}
run: uv tree -d 1 --outdated --only-dev | grep -e "^├.*latest.*" || true | tee ./reports/security/outdated-dependencies-dev.txt | awk 'NF {print "::notice title=Outdated dev/test Dependency::" $0}'
shell: bash
- name: Run security checks
if: ${{ !steps.security.outputs.cache-hit }}
run: bandit -r src | tee ./reports/security/code-scan.txt
shell: bash
analysis:
name: Static Analysis
runs-on: ubuntu-24.04
needs: prebuild
if: ${{ needs.prebuild.outputs.analysis-cache-hit != 'true' }}
concurrency:
group: analysis-${{ github.sha }}
steps:
- name: Fetch static analysis result cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: analysis
with:
path: ./reports/analysis/*
key: analysis-${{ github.sha }}
- name: Report on cache
if: ${{ steps.analysis.outputs.cache-hit }}
run: |
echo "::notice::Skipping static analysis steps due to cached analysis report for this commit."
- name: Checkout codebase
if: ${{ !steps.analysis.outputs.cache-hit }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Prepare the Python environment
if: ${{ !steps.analysis.outputs.cache-hit }}
uses: ./.github/actions/prepare
- name: Check for unused dependencies
if: ${{ !steps.analysis.outputs.cache-hit }}
run: deptry ./src | tee ./reports/analysis/unused-dependencies.txt
shell: bash
- name: Perform Ruff rule checks
if: ${{ !steps.analysis.outputs.cache-hit }}
run: ruff check | tee ./reports/analysis/code-rules.txt
shell: bash
- name: Perform Pyright typing checks
if: ${{ !steps.analysis.outputs.cache-hit }}
env:
PYRIGHT_PYTHON_PYLANCE_VERSION: latest-release
run: pyright ./src | tee ./reports/analysis/typing.txt
shell: bash
build:
name: Build Package
runs-on: ubuntu-24.04
needs: [prebuild, tests, compatibility, security, analysis]
if: ${{ !failure() && !cancelled() && needs.prebuild.outputs.build-cache-hit != 'true' && needs.prebuild.result != 'skipped' }}
concurrency:
group: build-${{ github.sha }}
steps:
# If a version tag, cache packages for possible deploy
- name: Fetch build cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
id: build
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
with:
path: |
./dist
key: build-${{ github.sha }}
- name: Report on cache
if: ${{ steps.build.outputs.cache-hit }}
run: |
echo "::notice::Skipping build steps due to cached build result for this commit."
- name: Checkout codebase
if: ${{ !steps.build.outputs.cache-hit }}
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Prepare the Python environment
if: ${{ !steps.build.outputs.cache-hit }}
uses: ./.github/actions/prepare
- name: Build packages
if: ${{ !steps.build.outputs.cache-hit }}
shell: bash
run: uv build
- name: Check package description
if: ${{ !steps.build.outputs.cache-hit }}
run: twine check --strict ./dist/*