Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
35 changes: 33 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: CI/CD

permissions:
contents: write
on:
push:
branches: [main]
Expand All @@ -16,7 +17,8 @@ jobs:

steps:
- uses: actions/checkout@v4

with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v5

Expand Down Expand Up @@ -64,6 +66,35 @@ jobs:
# Upload coverage (if tests are being run)
# - name: Upload coverage
# uses: codecov/codecov-action@v4
license-check:
name: License Compliance Check
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.21'

- name: Cache Go bin path
run: echo "$(go env GOPATH)/bin" >> $GITHUB_PATH

- name: Install addlicense
run: go install github.com/google/addlicense@latest

- name: Run addlicense check (only on relevant files)
run: |
year=$(date +'%Y')
find . -type f \( -name '*.py' -o -name '*.sh' -o -name '*.go' \) \
-not -path './.git/*' \
-not -path './.venv/*' \
-not -path './vendor/*' \
| xargs $(go env GOPATH)/bin/addlicense -check -c "Steve Morin" -l mit -y "$year" -s -v

# Only run security checks on pull requests from the main repository
security:
Expand Down
10 changes: 8 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
Expand Down Expand Up @@ -47,4 +46,11 @@ repos:
language: system
types: [python]
pass_filenames: false # Run full test suite
stages: [pre-commit] # Only run on pre-commit
stages: [pre-commit] # Only run on commit
- repo: local
hooks:
- id: check-vscode-extension-sync
name: Check VSCode Extension Sync
entry: uvx scripts/check_extension_sync.py
language: system
types: [json]
24 changes: 18 additions & 6 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,21 @@ debug-info:
# Update CONTRIBUTORS.md file
[group('build')]
@contributors:
update-contributors:
echo "Updating CONTRIBUTORS.md..."
# Cross-platform way to update CONTRIBUTORS.md using git shortlog
echo "# Contributors" > CONTRIBUTORS.md
echo "" >> CONTRIBUTORS.md
git shortlog -sne >> CONTRIBUTORS.md
echo "✓ Contributors list updated"
if [ "$$OS" = "Windows_NT" ]; then \
powershell -File scripts/update_contributors.ps1; \
else \
echo "{{YELLOW}}TODO: Add macOS/Linux command to update CONTRIBUTORS.md here{{NC}}"; \
# Example placeholder: ./scripts/update_contributors.sh
fi
echo "{{CHECK}} Contributors list updated"

# # Generate changelog from conventional commits
# changelog:
# echo "Generating changelog..."
# command -v cog >/dev/null 2>&1 || { echo "{{RED}}Error: Cocogitto (cog) is not installed{{NC}}"; exit 1; }
# cog changelog --at=HEAD
# echo "{{GREEN}}✓{{NC}} Changelog generated"

# Verify commit messages follow conventional commit format
[group('pre-commit')]
Expand Down Expand Up @@ -628,5 +636,9 @@ clean-pr-to-testrepo new_repo_name="test-actions-repo":
# just build
# just run

# Check if VSCode recommended extensions are synced with devcontainer
check-extension-sync:
uv run scripts/check_extension_sync.py

# Alias for dev (full developer cycle: format → lint → test → build)
alias cycle := dev
52 changes: 52 additions & 0 deletions scripts/check_extension_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3

import json
import sys
import os
from pathlib import Path

EXTENSIONS_FILE = Path(".vscode/extensions.json")
DEVCONTAINER_FILE = Path(".devcontainer/devcontainer.json")

def load_json(file_path):
try:
with open(file_path) as f:
return json.load(f)
except FileNotFoundError:
print(f"❌ Error: {file_path} not found.")
sys.exit(2)
except json.JSONDecodeError as e:
print(f"❌ Error parsing {file_path}: {e}")
sys.exit(2)

def extract_recommended_extensions(data):
return set(data.get("recommendations", []))

def extract_devcontainer_extensions(data):
try:
return set(data["customizations"]["vscode"]["extensions"])
except KeyError:
return set()

def main():
vscode_data = load_json(EXTENSIONS_FILE)
devcontainer_data = load_json(DEVCONTAINER_FILE)

vscode_exts = extract_recommended_extensions(vscode_data)
dev_exts = extract_devcontainer_extensions(devcontainer_data)

missing = vscode_exts - dev_exts

if missing:
print("❌ VSCode extensions not synced with devcontainer configuration!\n")
print("Missing from .devcontainer/devcontainer.json:")
for ext in sorted(missing):
print(f"- {ext}")
print("\nTo fix: Add these extensions to the `customizations.vscode.extensions` array in `.devcontainer/devcontainer.json`")
sys.exit(1)

print("✅ VSCode extensions are in sync.")
sys.exit(0)

if __name__ == "__main__":
main()
Loading