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: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ src/main/resources/META-INF/resources/assets/** linguist-generated
# Install scripts -- enforce correct line endings per platform
*.sh text eol=lf
*.ps1 text eol=crlf

# Git hooks have no extension, so *.sh above does not reach them. They are LF in
# the repo today only by luck: a CRLF hook is not merely untidy, it fails to
# execute on Linux and macOS ("bad interpreter"), which would silently disarm the
# force-push guard for everyone who activated it.
.githooks/** text eol=lf
4 changes: 2 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ Closes #

## Checklist

- [ ] My code follows the project's [code style](CONTRIBUTING.md#code-style)
- [ ] My code follows the project's [code style](https://github.com/labsai/EDDI/blob/main/CONTRIBUTING.md#code-style)
- [ ] I have added tests that prove my fix/feature works
- [ ] Existing tests pass locally (`./mvnw clean verify -DskipITs`)
- [ ] I have updated documentation if needed
- [ ] My commit messages follow [conventional commits](CONTRIBUTING.md#commit-convention)
- [ ] My commit messages follow [conventional commits](https://github.com/labsai/EDDI/blob/main/CONTRIBUTING.md#commit-convention)
- [ ] I have not committed any secrets, API keys, or tokens
- [ ] This PR has a clear, focused scope (one concern per PR)
16 changes: 16 additions & 0 deletions .github/workflows/auto-approve-copilot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,22 @@ jobs:
continue;
}

// "Every check that ran was green" is not the same claim as "CI
// ran". A merge-conflicted PR never triggers CI/CD at all, so the
// loop above sees only CodeQL et al. and finds nothing failing —
// and the approval body would then assert that all CI checks
// passed on a commit that was never built. Require the gating
// jobs to be PRESENT by name, so absence is a reason to wait
// rather than a silent pass.
const REQUIRED_CHECKS = ['Build & Test', 'Integration Tests'];
const present = new Set(relevant.map(c => c.name));
const absent = REQUIRED_CHECKS.filter(name => !present.has(name));
if (absent.length > 0) {
core.info(`PR #${number}: required check(s) never reported: ${absent.join(', ')} `
+ `(merge conflict, or CI did not trigger). Not approving.`);
continue;
}

await github.rest.pulls.createReview({
owner, repo, pull_number: number, event: 'APPROVE',
body: 'Auto-approved: GitHub Copilot reviewed with no unresolved comments and all CI checks passed.\n\n'
Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
code: ${{ steps.result.outputs.code }}
scripts: ${{ steps.result.outputs.scripts }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
Expand All @@ -49,6 +50,15 @@ jobs:
- 'helm/**'
- 'mvnw*'
- '.mvn/**'
# The installers are the README's headline `curl | bash` path and were
# in NO filter at all, so a PR touching only them skipped the whole
# pipeline — and a skipped required check still satisfies branch
# protection. They do not need the Java build, just the shell lint.
scripts:
- 'install.sh'
- 'install.ps1'
- 'scripts/**'
- '.githooks/**'

- name: Resolve
id: result
Expand All @@ -61,8 +71,10 @@ jobs:
# with failing tests builds nothing.
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
echo "code=true" >> $GITHUB_OUTPUT
echo "scripts=true" >> $GITHUB_OUTPUT
else
echo "code=${{ steps.filter.outputs.code }}" >> $GITHUB_OUTPUT
echo "scripts=${{ steps.filter.outputs.scripts }}" >> $GITHUB_OUTPUT
fi

- name: Log result
Expand All @@ -76,6 +88,79 @@ jobs:
echo "- ⏭️ Skipping build/test/docker (docs/licenses/config-only change)" >> $GITHUB_STEP_SUMMARY
fi

# ─── Job 0b: Shell Lint ─────────────────────────────────────────
# install.sh is 55 KB, install.ps1 is 40 KB, and they are what the README tells
# people to pipe into a shell. Until this job existed nothing checked them at
# all — not a linter, not a test, not even a syntax parse.
shell-lint:
name: Shell Lint
runs-on: ubuntu-latest
needs: detect-changes
if: needs.detect-changes.outputs.scripts == 'true'

steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- name: Bash syntax check
# Catches the class of error that makes `curl | bash` fail at the worst
# possible moment — on a user's machine, halfway through an install.
run: |
for f in install.sh .githooks/*; do
[ -f "$f" ] || continue
head -n1 "$f" | grep -qE '^#!.*(bash|sh)' || continue
echo "checking $f"
bash -n "$f"
done

- name: ShellCheck
# Uses the shellcheck preinstalled on ubuntu-latest rather than a
# third-party action, so there is no extra supply-chain edge to pin.
run: |
shellcheck --version
shellcheck --severity=warning --shell=bash install.sh

- name: PowerShell syntax check
shell: pwsh
run: |
# Parse-only: never dot-source or run the installer in CI.
# Covers scripts/ too — preflight-local.ps1 is a contributor-facing
# script and was as unchecked as the installers were.
$ErrorActionPreference = 'Stop'
$failed = $false
Get-ChildItem -Path ./install.ps1, ./scripts -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue |
ForEach-Object {
$errors = $null
[System.Management.Automation.Language.Parser]::ParseFile($_.FullName, [ref]$null, [ref]$errors) | Out-Null
if ($errors) {
$failed = $true
$name = Resolve-Path -Relative $_.FullName
$errors | ForEach-Object { Write-Host "::error file=$name,line=$($_.Extent.StartLineNumber)::$($_.Message)" }
} else {
Write-Host "$($_.Name) parses cleanly"
}
}
if ($failed) { exit 1 }

- name: PSScriptAnalyzer
shell: pwsh
run: |
# Preinstalled on the runner; installing over it only emits a
# "currently in use" warning.
if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
Install-Module PSScriptAnalyzer -Force -Scope CurrentUser -ErrorAction Stop
}
$targets = @('./install.ps1')
if (Test-Path ./scripts) { $targets += './scripts' }
# -Path takes ONE string, not an array — passing @(...) fails with
# "Cannot convert 'System.Object[]' to the type 'System.String'".
$found = @()
foreach ($t in $targets) {
$found += Invoke-ScriptAnalyzer -Path $t -Recurse -Severity Error,Warning
}
$found | Format-Table -AutoSize | Out-String | Write-Host
if ($found | Where-Object { $_.Severity -eq 'Error' }) { exit 1 }
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# ─── Job 1: Build & Test ────────────────────────────────────────
build-and-test:
name: Build & Test
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ fabric.properties
docker/data/
/tmp/

# Grafana runtime state. The monitoring stack uses a named Docker volume and
# provisions from docs/monitoring/, so anything written here is local scratch —
# grafana.db (a 1.4 MB SQLite file) used to be committed from the bind-mount era.
/grafana-data/

# Kubernetes — user-specific values and Helm packaging output
helm/eddi/charts/
*.tgz
Expand Down
4 changes: 4 additions & 0 deletions docker-compose.monitoring.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ services:
- "3000:3000"
volumes:
- ./docs/monitoring/eddi-grafana-dashboard.json:/var/lib/grafana/dashboards/eddi.json:ro
# The provider globs this directory, so a second dashboard needs no
# provisioning change. Was stranded in a top-level grafana-data/ left over
# from the bind-mount era and provisioned by nothing.
- ./docs/monitoring/eddi-operations-dashboard.json:/var/lib/grafana/dashboards/eddi-operations.json:ro
- ./docs/monitoring/grafana-provisioning/datasources:/etc/grafana/provisioning/datasources:ro
- ./docs/monitoring/grafana-provisioning/dashboards:/etc/grafana/provisioning/dashboards:ro
- grafana-data:/var/lib/grafana
Expand Down
3 changes: 3 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@
- [Audit Ledger](audit-ledger.md)
- [GDPR / CCPA Compliance](gdpr-compliance.md)
- [HIPAA Compliance](hipaa-compliance.md)
- [Business Associate Agreement (BAA) Template](templates/baa-template.md)
- [EU AI Act Compliance](eu-ai-act-compliance.md)
- [Compliance Data Flow](compliance-data-flow.md)
- [Incident Response Plan](incident-response.md)
- [Security Review](security-review.md)
- [Privacy & Data Processing](../PRIVACY.md)

## Advanced Concepts
Expand All @@ -84,6 +86,7 @@
- [Setting Up EDDI on AWS with MongoDB Atlas](setup-eddi-on-aws-with-mongodb-atlas.md)
- [Release & Versioning Strategy](release-versioning.md)
- [Release Signing & Verification](release-signing.md)
- [Release Notes — 6.0.2](release-notes-6.0.2.md)
- [Metrics & Monitoring](metrics.md)
- [Monitoring & Tracing Guide](monitoring/monitoring-guide.md)
- [Log Administration](log-administration.md)
Expand Down
Loading
Loading