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
41 changes: 41 additions & 0 deletions .github/workflows/actionlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Workflow lint

# actionlint catches what a YAML parser cannot: duplicate mapping keys that
# make GitHub refuse to load a workflow, invalid ${{ }} expressions, and shell
# problems inside run: blocks. A duplicate env: key silently broke this repo
# family's release workflow once; yaml.safe_load keeps the last value without
# complaining, so local validation passed while Actions rejected the file.
on:
push:
branches: [main]
paths: ['.github/workflows/**']
pull_request:
paths: ['.github/workflows/**']
workflow_dispatch:

permissions:
contents: read

jobs:
actionlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.1

# Fetched and checksum-verified rather than run as a third-party action,
# so this check adds no new action to the supply chain it exists to guard.
- name: Install actionlint
env:
ACTIONLINT_VERSION: 1.7.12
ACTIONLINT_SHA256: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8
run: |
set -euo pipefail
archive="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
curl -sSfL -o "$archive" \
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/${archive}"
echo "${ACTIONLINT_SHA256} ${archive}" | sha256sum -c -
tar -xzf "$archive" actionlint
install -m 0755 actionlint /usr/local/bin/actionlint

- name: Lint workflows
run: actionlint -color
53 changes: 53 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import base64
import json
import pathlib
import subprocess
import sys
import textwrap
import time

import pytest
Expand Down Expand Up @@ -206,3 +209,53 @@ def attestation_report(trust_record: dict) -> dict:
"timestamp": trust_record["trace"]["iat"],
"cnf_key_x": trust_record["trace"]["cnf"]["jwk"]["x"],
}


# --- environment guard ---
#: Packages this suite is meant to exercise from source.
_PACKAGES_UNDER_TEST = ("trace_tests",)

#: Repository root, resolved from this file.
_REPO_ROOT = pathlib.Path(__file__).resolve().parents[1]

_PROBE = textwrap.dedent(
"""
import importlib, sys
try:
m = importlib.import_module(sys.argv[1])
except Exception:
print("")
else:
print(getattr(m, "__file__", "") or "")
"""
)


def _subprocess_origin(package: str) -> pathlib.Path | None:
"""Where a fresh interpreter finds ``package``, or None if it cannot."""
try:
done = subprocess.run(
[sys.executable, "-c", _PROBE, package],
capture_output=True,
text=True,
timeout=60,
check=False, # a non-zero exit just means "cannot import", handled below
)
except (OSError, subprocess.SubprocessError):
return None
origin = done.stdout.strip()
return pathlib.Path(origin).resolve() if origin else None


def pytest_configure(config: pytest.Config) -> None:
for name in _PACKAGES_UNDER_TEST:
origin = _subprocess_origin(name)
if origin is None:
continue # not importable from a subprocess; nothing can shadow
if _REPO_ROOT not in origin.parents:
raise pytest.UsageError(
f"{name} resolves to {origin} in a subprocess, outside "
f"{_REPO_ROOT}. Any test that shells out would exercise that "
"installed distribution instead of this working tree. Install "
f"editable (pip install -e .) or uninstall the shadowing {name}."
)