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
50 changes: 50 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "OpenContext",
"image": "mcr.microsoft.com/devcontainers/python:3.11",

"features": {
"ghcr.io/devcontainers/features/go:1": {
"version": "latest"
},
"ghcr.io/devcontainers-contrib/features/uv:1": {}
},

"postCreateCommand": {
"python": "uv sync --all-extras && pre-commit install",
"claude": "curl -fsSL https://claude.ai/install.sh | bash"
},

// Local MCP dev server
"forwardPorts": [8000],
"portsAttributes": {
"8000": {
"label": "MCP Server",
"onAutoForward": "notify"
}
},

"customizations": {
"vscode": {
"extensions": [
"charliermarsh.ruff",
"ms-python.python",
"ms-python.vscode-pylance",
"golang.go",
"redhat.vscode-yaml",
"hashicorp.terraform",
"tamasfe.even-better-toml"
],
"settings": {
"python.defaultInterpreterPath": ".venv/bin/python",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit"
}
},
"ruff.lint.args": ["--config=pyproject.toml"]
}
}
}
}
36 changes: 30 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ on:
- develop

jobs:
code-quality:
name: Code quality
lint:
name: Lint & format
runs-on: ubuntu-latest

steps:
Expand All @@ -37,9 +37,6 @@ jobs:
- name: Ruff lint
run: uv run ruff check core/ plugins/ server/ tests/

- name: Audit dependencies for known CVEs
run: uv run pip-audit -r requirements.txt

- name: Set up Go 1.21
uses: actions/setup-go@v5
with:
Expand All @@ -55,8 +52,35 @@ jobs:
exit 1
fi

test-suite:
security:
name: Security audit
needs: lint
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: "uv.lock"

- name: Install dependencies
run: uv sync --all-extras

- name: Audit dependencies for known CVEs
run: uv run pip-audit -r requirements.txt

test:
name: Test suite
needs: lint
runs-on: ubuntu-latest

steps:
Expand Down
63 changes: 34 additions & 29 deletions .github/workflows/infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,63 @@ on:
- "terraform/**"

jobs:
terraform-validate:
name: Terraform validate
terraform-lint:
name: Terraform lint & validate
runs-on: ubuntu-latest
env:
TF_PLUGIN_CACHE_DIR: ${{ runner.temp }}/.terraform.d/plugin-cache

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Cache Terraform providers
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/.terraform.d/plugin-cache
key: ${{ runner.os }}-terraform-${{ hashFiles('terraform/**/.terraform.lock.hcl') }}

- name: Cache Terraform init
uses: actions/cache@v4
with:
path: terraform/aws/.terraform
key: ${{ runner.os }}-tf-init-${{ hashFiles('terraform/**/.terraform.lock.hcl') }}

- name: Set up Terraform
uses: hashicorp/setup-terraform@v3

- name: Check Terraform formatting
working-directory: ./terraform
run: |
if ! terraform fmt -check -recursive; then
echo "Terraform files are not properly formatted."
echo "::error::Terraform files are not properly formatted."
echo "Run 'terraform fmt -recursive' locally and commit the result."
exit 1
fi

- name: Terraform init (no backend)
working-directory: ./terraform/aws
run: terraform init -backend=false

- name: Create placeholder Lambda zip for validation
working-directory: ./terraform/aws
- name: Create placeholder artifacts for validation
run: |
python3 -c "import zipfile; zipfile.ZipFile('lambda-deployment.zip', 'w').close()"
python3 -c "import zipfile; zipfile.ZipFile('terraform/aws/lambda-deployment.zip', 'w').close()"

- name: Terraform validate
working-directory: ./terraform/aws
run: terraform validate
- name: Validate all Terraform directories
run: |
failed=0
for dir in terraform/*/; do
if ls "$dir"*.tf 1>/dev/null 2>&1; then
echo "--- Validating $dir ---"
terraform -chdir="$dir" init -backend=false -input=false
if ! terraform -chdir="$dir" validate; then
echo "::error::Validation failed in $dir"
failed=1
fi
else
echo "--- Skipping $dir (no .tf files) ---"
fi
done
exit $failed

- name: Set up TFLint
uses: terraform-linters/setup-tflint@v4

- name: Run TFLint
run: tflint --chdir=terraform/aws
- name: Run TFLint on all directories
run: |
failed=0
for dir in terraform/*/; do
if ls "$dir"*.tf 1>/dev/null 2>&1; then
echo "--- TFLint: $dir ---"
if ! tflint --chdir="$dir"; then
echo "::warning::TFLint issues in $dir"
failed=1
fi
fi
done
exit $failed

- name: Run tfsec
uses: aquasecurity/tfsec-action@v1.0.3
Expand Down
70 changes: 63 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ name: Release
on:
push:
tags:
- "v*.*.*" # Triggers on version tags like v1.0.0, v2.1.3, etc.
workflow_dispatch: # Allows manual triggering
- "v*.*.*"
workflow_dispatch:
inputs:
version:
description: "Version tag (e.g., v1.0.0)"
Expand All @@ -17,11 +17,68 @@ env:
GO_VERSION: "1.21"

jobs:
validate:
name: Pre-release validation
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
cache-dependency-glob: "uv.lock"

- name: Install dependencies
run: uv sync --all-extras

- name: Ruff lint
run: uv run ruff check core/ plugins/ server/ tests/

- name: Audit dependencies for known CVEs
run: uv run pip-audit -r requirements.txt

- name: Run Python tests with coverage
run: |
uv run pytest tests/ \
-n auto \
--cov=core \
--cov=plugins \
--cov-report=term-missing \
--cov-fail-under=80

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Check Go formatting
working-directory: ./client
run: |
UNFORMATTED=$(gofmt -l .)
if [ -n "$UNFORMATTED" ]; then
echo "The following files need formatting:"
echo "$UNFORMATTED"
exit 1
fi

- name: Run Go tests
working-directory: ./client
run: go test ./...

build:
name: Build binaries
needs: validate
runs-on: ubuntu-latest
permissions:
contents: write # Required to create releases and upload assets
contents: write

strategy:
matrix:
Expand All @@ -46,7 +103,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for proper versioning
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
Expand Down Expand Up @@ -84,6 +141,7 @@ jobs:

build-lambda-zip:
name: Build Lambda ZIP
needs: validate
runs-on: ubuntu-latest
permissions:
contents: write
Expand Down Expand Up @@ -119,7 +177,7 @@ jobs:
cp -r server/ package/server/
cp -r plugins/ package/plugins/
cp -r core/ package/core/
cp examples/boston-opendata/config.yaml package/config.yaml
cp config-example.yaml package/config.yaml

- name: Create Lambda ZIP
run: |
Expand Down Expand Up @@ -172,7 +230,6 @@ jobs:
run: |
cd artifacts
echo "=== Flattening artifacts ==="
# Find all release files (binaries + lambda zip) in subdirectories and move to root
find . -mindepth 2 -type f \( -name "opencontext-client-*" -o -name "opencontext-lambda-*" \) | while read file; do
filename=$(basename "$file")
dirname=$(dirname "$file")
Expand All @@ -182,7 +239,6 @@ jobs:
rmdir "$dirname" 2>/dev/null || true
mv "$tempname" "$filename"
done
# Remove any remaining empty subdirectories
find . -mindepth 1 -type d -empty -delete
echo "=== Flattening complete ==="

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,7 @@ client/opencontext-client-*
# Config yaml
config.yaml
examples/

# Terraform variable files (may contain real secrets — use *.tfvars.example as templates)
terraform/**/*.tfvars
.claude/
Loading
Loading