Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/actions/bootstrap/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ runs:
echo "run_script=uv run --frozen" | Tee-Object -Append $env:GITHUB_ENV

- name: Setup uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: "**/uv.lock"
python-version: ${{ inputs.python-version }}

- name: Install Task
uses: go-task/setup-task@v1
uses: go-task/setup-task@v2
with:
# Passing a repo token reduces the likelihood of API rate limit exceeded
repo-token: ${{ inputs.token }}
Expand Down Expand Up @@ -102,7 +102,7 @@ runs:
echo "PY=$hash" | Tee-Object -Append $env:GITHUB_ENV

- name: Cache pre-commit environments
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles(format('{0}/.pre-commit-config.yaml', inputs.working-directory)) }}
Expand Down
29 changes: 17 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
- name: Run SBOM generation
run: task -v sbom
- name: Upload SBOM artifacts
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: sbom-files
path: |
Expand All @@ -89,15 +89,15 @@ jobs:
- name: Check license compliance
run: task -v license-check
- name: Upload license check results
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: license-check-results
path: license-check.json
if-no-files-found: error
- name: Run vulnerability scan
run: task -v vulnscan
- name: Upload vulnerability scan results
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: vuln-scan-results
path: vulns.json
Expand All @@ -111,11 +111,14 @@ jobs:
# out the repo on Windows. Instead, cookiecutter fetches the template
# directly from the remote branch.
- name: Setup uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ env.python_version }}
# No checkout in this job (NTFS-illegal chars in template dir), so disable cache
enable-cache: false
ignore-empty-workdir: true
- name: Install Task
uses: go-task/setup-task@v1
uses: go-task/setup-task@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate project from template
Expand All @@ -138,11 +141,13 @@ jobs:
curl -fsSL "$scriptUrl" -o "$tmpdir/extract_template_zip.py"
repoDir=$(python3 "$tmpdir/extract_template_zip.py" "$tmpdir/template.zip" "$tmpdir/src")

uvx --with gitpython cookiecutter "$repoDir" --no-input --output-dir "$RUNNER_TEMP"
uvx --with gitpython cookiecutter "$repoDir" --no-input \
project_name="ci-test-project" \
--output-dir "$RUNNER_TEMP"
- name: Verify generated project
shell: pwsh
run: |
$project = Join-Path $env:RUNNER_TEMP "replace-me"
$project = Join-Path $env:RUNNER_TEMP "ci-test-project"

# Verify the project directory was created
if (-not (Test-Path $project)) {
Expand Down Expand Up @@ -219,25 +224,25 @@ jobs:
- name: Initialize generated project
shell: bash
run: |
cd "$RUNNER_TEMP/replace-me"
cd "$RUNNER_TEMP/ci-test-project"
task -v init
- name: Run unit tests
shell: bash
# Integration tests require Docker (Linux images) which is not
# available on Windows runners; those are covered by the Linux CI job.
run: |
cd "$RUNNER_TEMP/replace-me"
cd "$RUNNER_TEMP/ci-test-project"
task -v unit-test
- name: Build Docker image
shell: bash
run: |
cd "$RUNNER_TEMP/replace-me"
cd "$RUNNER_TEMP/ci-test-project"
task -v build
- name: Verify Docker image
shell: bash
run: |
docker run --rm zenable-io/replace-me:latest --version
docker run --rm zenable-io/replace-me:latest --help
docker run --rm zenable-io/ci-test-project:latest --version
docker run --rm zenable-io/ci-test-project:latest --help
- name: Verify zenable CLI
shell: bash
run: |
Expand Down
4 changes: 3 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ tasks:
# This fixes an "ERROR: Multiple platforms feature is currently not supported for docker driver" pipeline error
# Only create our multiplatform builder if it doesn't already exist; otherwise list information about the one that exists
# It suppresses the inspect output when it's not running in a GitHub Action
- docker buildx inspect multiplatform {{if ne .GITHUB_ACTIONS "true"}}>/dev/null{{end}} || docker buildx create --name multiplatform --driver docker-container --use
- docker buildx inspect multiplatform {{if ne .GITHUB_ACTIONS "true"}}>/dev/null{{end}} 2>/dev/null || docker buildx create --name multiplatform --driver docker-container --use

init:
desc: Initialize the repo for local use; intended to be run after git clone
Expand Down Expand Up @@ -152,6 +152,8 @@ tasks:
-w /src \
anchore/syft:latest \
/src \
--source-name={{.PROJECT_SLUG}} \
--source-version={{.VERSION}} \
-o syft-json=sbom.syft.json \
-o spdx-json=sbom.spdx.json \
-o cyclonedx-json=sbom.cyclonedx.json
Expand Down
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[project]
name = "ai-native-python"
# Automatically updated by the release task via python-semantic-release (see Taskfile.yml and [tool.semantic_release] below)
version = "0.4.1"
description = "The AI-Native python paved road generator"
authors = [
Expand Down Expand Up @@ -50,8 +51,12 @@ ignore = [
plugins = []

[tool.pytest.ini_options]
addopts = "--cov=ai_native_python --cov-append --no-cov-on-fail --cov-fail-under=0 --cov-report=html --cov-report=xml --cov-report=term-missing"
addopts = "--cov=ai_native_python --cov=hooks --cov-append --no-cov-on-fail --cov-fail-under=0 --cov-report=html --cov-report=xml --cov-report=term-missing"
pythonpath = ['.']
filterwarnings = [
# Tests invoke hooks via cookiecutter subprocess, so coverage can't track them directly
"ignore:No data was collected:coverage.exceptions.CoverageWarning",
]
markers = [
"unit: marks tests as unit tests (deselect with '-m \"not unit\"')",
"integration: marks tests as integration tests (deselect with '-m \"not integration\"')",
Expand Down
5 changes: 5 additions & 0 deletions scripts/scan_workflow_logs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ find . -type f -name "*.txt" | while IFS= read -r logfile; do
# Sanitize content to prevent command injection and log poisoning
sanitized_content=$(echo "$content" | tr -d '\n\r' | cut -c1-200)

# Skip JSON data lines (e.g. SBOM/license check output with package names like "deprecated")
if echo "$content" | grep -qE '"(id|name)":\s*"'; then
continue
fi

# Determine the type of issue and output both annotation and count
if echo "$content" | grep -qiE '\berror\b'; then
echo "::error file=$job_name,line=$line_num::$sanitized_content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ runs:
echo "run_script=${run_script}" | tee -a "${GITHUB_ENV}"

- name: Setup uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: "**/uv.lock"
python-version: ${{ "{{ inputs.python-version }}" }}

- name: Install Task
uses: go-task/setup-task@v1
uses: go-task/setup-task@v2
with:
# Passing a repo token reduces the likelihood of API rate limit exceeded
repo-token: ${{ "{{ inputs.token }}" }}
Expand Down Expand Up @@ -74,7 +74,7 @@ runs:
echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" | tee -a "${GITHUB_ENV}"

- name: Cache pre-commit environments
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ "{{ env.PY }}" }}|${{ "{{ hashFiles(format('{0}/.pre-commit-config.yaml', inputs.working-directory)) }}" }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ jobs:
- name: Set env var for unique artifact uploads
run: echo SANITIZED_PLATFORM="$(echo "${{ "{{ matrix.platform }}" }}" | sed 's/\//_/g')" | tee -a "${GITHUB_ENV}"
- name: Upload SBOM artifacts
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: sbom-${{ "{{ env.SANITIZED_PLATFORM }}" }}
path: |
Expand All @@ -112,7 +112,7 @@ jobs:
env:
PLATFORM: ${{ "{{ matrix.platform }}" }}
- name: Upload license check results
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: license-check-${{ "{{ env.SANITIZED_PLATFORM }}" }}
path: license-check.*.json
Expand All @@ -122,7 +122,7 @@ jobs:
env:
PLATFORM: ${{ "{{ matrix.platform }}" }}
- name: Upload vulnerability scan results
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: vulns-${{ "{{ env.SANITIZED_PLATFORM }}" }}
path: vulns.*.json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
- name: Set env var for unique artifact uploads
run: echo SANITIZED_PLATFORM="$(echo "${{ "{{ matrix.platform }}" }}" | sed 's/\//_/g')" | tee -a "${GITHUB_ENV}"
- name: Upload SBOM artifacts
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: sbom-${{ "{{ env.SANITIZED_PLATFORM }}" }}
path: |
Expand All @@ -87,7 +87,7 @@ jobs:
env:
PLATFORM: ${{ "{{ matrix.platform }}" }}
- name: Upload license check results
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: license-check-${{ "{{ env.SANITIZED_PLATFORM }}" }}
path: license-check.*.json
Expand All @@ -97,7 +97,7 @@ jobs:
env:
PLATFORM: ${{ "{{ matrix.platform }}" }}
- name: Upload vulnerability scan results
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v7
with:
name: vulns-${{ "{{ env.SANITIZED_PLATFORM }}" }}
path: vulns.*.json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ tasks:
# This fixes an "ERROR: Multiple platforms feature is currently not supported for docker driver" pipeline error
# Only create our multiplatform builder if it doesn't already exist; otherwise list information about the one that exists
# It suppresses the inspect output when it's not running in a GitHub Action
- docker buildx inspect multiplatform {{ '{{if ne .GITHUB_ACTIONS "true"}}' }}>/dev/null{{ '{{end}}' }} || docker buildx create --name multiplatform --driver docker-container --use
- docker buildx inspect multiplatform {{ '{{if ne .GITHUB_ACTIONS "true"}}' }}>/dev/null{{ '{{end}}' }} 2>/dev/null || docker buildx create --name multiplatform --driver docker-container --use

init:
desc: Initialize the repo for local use; intended to be run after git clone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pythonpath = ['src']
markers = [
"unit: marks tests as unit tests (deselect with '-m \"not unit\"')",
"integration: marks tests as integration tests (deselect with '-m \"not integration\"')",
"slow: marks tests as slow tests (deselect with '-m \"not slow\"')",
]

[tool.uv]
Expand Down
7 changes: 4 additions & 3 deletions {{cookiecutter.project_name|replace(" ", "")}}/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@

def main():
"""Main entry point for the application."""
parser = argparse.ArgumentParser(description="{{ cookiecutter.project_short_description | replace('"', '\\"') | replace("'", "\\\\'") }}")
parser.add_argument(
"--version", action="version", version=f"%(prog)s {__version__}"
parser = argparse.ArgumentParser(
prog="{{ cookiecutter.project_slug }}",
description="{{ cookiecutter.project_short_description | replace('"', '\\"') | replace("'", "\\\\'") }}",
)
parser.add_argument("--version", action="version", version=__version__)
parser.parse_args()

log = config.setup_logging()
Expand Down
Loading