Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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.
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