Spaces:
Sleeping
Sleeping
| # STEM BIO-AI Snapshot Provenance Collector | |
| # Usage: bash snapshot_provenance.sh /path/to/repo | |
| # Output: provenance data for audit trail | |
| set -euo pipefail | |
| REPO_PATH="${1:-.}" | |
| print_help() { | |
| echo "STEM BIO-AI Snapshot Provenance Collector" | |
| echo "" | |
| echo "Usage: bash snapshot_provenance.sh [REPO_PATH]" | |
| echo "" | |
| echo " REPO_PATH Path to local repository clone (default: current directory)" | |
| echo "" | |
| echo "Collects: commit hash, branch, README hash, file checksums," | |
| echo "access timestamp, remote URL for audit trail evidence." | |
| } | |
| if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then | |
| print_help | |
| exit 0 | |
| fi | |
| if [ ! -d "$REPO_PATH" ]; then | |
| echo "ERROR: Directory not found: $REPO_PATH" | |
| exit 1 | |
| fi | |
| cd "$REPO_PATH" | |
| echo "=== STEM BIO-AI Snapshot Provenance ===" | |
| echo "Collection Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| echo "Repo Path: $(pwd)" | |
| echo "" | |
| # Git information | |
| if [ -d ".git" ]; then | |
| echo "--- Git Provenance ---" | |
| echo "Current Branch: $(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" | |
| echo "HEAD Commit: $(git rev-parse HEAD 2>/dev/null || echo 'unknown')" | |
| echo "HEAD Short: $(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" | |
| echo "Commit Date: $(git log -1 --format=%ci 2>/dev/null || echo 'unknown')" | |
| echo "Commit Author: $(git log -1 --format='%an <%ae>' 2>/dev/null || echo 'unknown')" | |
| echo "Remote URL: $(git remote get-url origin 2>/dev/null || echo 'none')" | |
| echo "Total Commits: $(git rev-list --count HEAD 2>/dev/null || echo 'unknown')" | |
| echo "Tags: $(git tag --list 2>/dev/null | tr '\n' ', ' || echo 'none')" | |
| echo "" | |
| else | |
| echo "--- Git Provenance ---" | |
| echo "WARNING: Not a git repository" | |
| echo "" | |
| fi | |
| # Key file checksums | |
| echo "--- File Checksums (SHA-256) ---" | |
| KEY_FILES="README.md CHANGELOG.md LICENSE requirements.txt pyproject.toml setup.cfg package.json" | |
| for f in $KEY_FILES; do | |
| if [ -f "$f" ]; then | |
| HASH=$(sha256sum "$f" 2>/dev/null | cut -d' ' -f1 || echo 'hash_error') | |
| SIZE=$(wc -c < "$f" 2>/dev/null || echo '0') | |
| echo "$f: $HASH ($SIZE bytes)" | |
| fi | |
| done | |
| echo "" | |
| # CI/CD presence | |
| echo "--- CI/CD Artifacts ---" | |
| if [ -d ".github/workflows" ]; then | |
| echo "GitHub Actions workflows:" | |
| ls -1 .github/workflows/ 2>/dev/null | |
| else | |
| echo "No .github/workflows/ directory" | |
| fi | |
| if [ -f ".gitlab-ci.yml" ]; then | |
| echo "GitLab CI: present" | |
| fi | |
| if [ -f "Jenkinsfile" ]; then | |
| echo "Jenkins: present" | |
| fi | |
| echo "" | |
| # Test directory | |
| echo "--- Test Infrastructure ---" | |
| TEST_DIRS=$(find . -maxdepth 3 -type d -name "test*" -o -name "spec" 2>/dev/null | head -10) | |
| if [ -n "$TEST_DIRS" ]; then | |
| echo "Test directories found:" | |
| echo "$TEST_DIRS" | |
| TEST_COUNT=$(find . -maxdepth 4 -name "test_*.py" -o -name "*_test.py" -o -name "*.test.js" -o -name "*.spec.ts" 2>/dev/null | wc -l) | |
| echo "Test file count: $TEST_COUNT" | |
| else | |
| echo "No test directories found" | |
| fi | |
| echo "" | |
| # License | |
| echo "--- License Surface ---" | |
| if [ -f "LICENSE" ] || [ -f "LICENSE.md" ] || [ -f "LICENSE.txt" ]; then | |
| LICENSE_FILE=$(ls LICENSE* 2>/dev/null | head -1) | |
| LICENSE_FIRST=$(head -5 "$LICENSE_FILE" 2>/dev/null | tr '\n' ' ') | |
| echo "License file: $LICENSE_FILE" | |
| echo "First line: $LICENSE_FIRST" | |
| else | |
| echo "WARNING: No LICENSE file found" | |
| fi | |
| echo "" | |
| echo "=== Provenance Collection Complete ===" | |