Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d8819e9
docs: add OWASP CI/CD hardening design spec
JCarlosHidalgo Jun 23, 2026
bbbb3a1
docs: add OWASP CI/CD hardening implementation plan
JCarlosHidalgo Jun 23, 2026
7faba1e
build: add NuGet lockfiles for all 5 backends
JCarlosHidalgo Jun 23, 2026
2e6feda
ci: pin third-party action SHAs in ci.yml
JCarlosHidalgo Jun 23, 2026
8987f92
ci: enforce NuGet lockfile via --locked-mode in backend restore
JCarlosHidalgo Jun 23, 2026
6d17493
ci: generate SPDX 2.2 SBOM per backend service after build
JCarlosHidalgo Jun 23, 2026
55aaf0d
ci: generate sha256 checksums for test report artifacts
JCarlosHidalgo Jun 23, 2026
5dd5771
build: switch backend runtime images to aspnet and run as non-root user
JCarlosHidalgo Jun 23, 2026
b2bc50f
build: verify SHA256 of RabbitMQ delayed-message-exchange plugin
JCarlosHidalgo Jun 23, 2026
abfcabd
ci: add Hadolint Dockerfile linting job to CI pipeline
JCarlosHidalgo Jun 23, 2026
1f5d8f2
ci: add CODEOWNERS for all repository areas
JCarlosHidalgo Jun 23, 2026
33395d8
ci: remove non-existent grpc-contracts path from CODEOWNERS
JCarlosHidalgo Jun 23, 2026
223b3a7
ci: add Dependabot configuration for NuGet, npm, and GitHub Actions
JCarlosHidalgo Jun 23, 2026
ebad042
ci: add branch protection runbook for main
JCarlosHidalgo Jun 23, 2026
cca8768
docs: record NuGet prefix reservation status in SECRETS.md
JCarlosHidalgo Jun 23, 2026
7b533f0
ci: extra files included
JCarlosHidalgo Jun 23, 2026
40afef5
Merge branch 'main' into docs/design-patterns
JCarlosHidalgo Jun 23, 2026
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
14 changes: 14 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* @JCarlosHidalgo

/apps/Auth/ @JCarlosHidalgo
/apps/Attendance/ @JCarlosHidalgo
/apps/CourseManagement/ @JCarlosHidalgo
/apps/Payment/ @JCarlosHidalgo
/apps/Credentials/ @JCarlosHidalgo

/apps/Frontend/ @JCarlosHidalgo

/infrastructure/ @JCarlosHidalgo
/.github/ @JCarlosHidalgo

/packages/ @JCarlosHidalgo
35 changes: 35 additions & 0 deletions .github/branch-protection-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Branch Protection Runbook — `main`

Branch protection is configured in the GitHub UI (not versionable as a repo file).
This document records the required settings and the equivalent CLI command so the
configuration is reproducible from this file.

## Required settings for `main`

- Require a pull request before merging
- Required approving reviews: 1
- Require review from Code Owners (CODEOWNERS file)
- Require status checks to pass before merging
- Require branches to be up to date before merging
- Required checks: `changes`, `ci-gate`
- Do not allow bypassing the above settings (enforce for administrators)
- Allow force pushes: disabled
- Allow deletions: disabled

## Apply via GitHub CLI

Run once after merging this file to `main`:

gh api repos/JCarlosHidalgo/DAMA/branches/main/protection \
--method PUT \
--field 'required_status_checks[strict]=true' \
--field 'required_status_checks[contexts][]=changes' \
--field 'required_status_checks[contexts][]=ci-gate' \
--field 'enforce_admins=true' \
--field 'required_pull_request_reviews[required_approving_review_count]=1' \
--field 'required_pull_request_reviews[require_code_owner_reviews]=true' \
--field 'restrictions=null'

## Verify current state

gh api repos/JCarlosHidalgo/DAMA/branches/main/protection
85 changes: 85 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
version: 2
updates:
# GitHub Actions — keeps pinned SHAs current
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "ci"

# NuGet — one entry per backend
- package-ecosystem: "nuget"
directory: "/apps/Auth/Backend"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "backend"

- package-ecosystem: "nuget"
directory: "/apps/Attendance/Backend"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "backend"

- package-ecosystem: "nuget"
directory: "/apps/CourseManagement/Backend"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "backend"

- package-ecosystem: "nuget"
directory: "/apps/Payment/Backend"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "backend"

- package-ecosystem: "nuget"
directory: "/apps/Credentials/Backend"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "backend"

- package-ecosystem: "nuget"
directory: "/packages/outbox"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "packages"

- package-ecosystem: "nuget"
directory: "/packages/unit-of-work"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "packages"

- package-ecosystem: "nuget"
directory: "/packages/grpc-contracts"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "packages"

# npm — Dependabot reads package.json; Bun is not natively supported.
# After each Dependabot PR, run `bun install` locally to update bun.lock before merging.
- package-ecosystem: "npm"
directory: "/apps/Frontend"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "frontend"
51 changes: 46 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
steps:
- uses: actions/checkout@v5

- uses: dorny/paths-filter@v4
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4
id: filter
with:
filters: |
Expand Down Expand Up @@ -64,6 +64,27 @@ jobs:
emit backends "${backends[@]}"
emit backends_testable "${testable[@]}"

lint-dockerfiles:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Lint Dockerfiles
run: |
for dockerfile in \
infrastructure/environments/auth/Dockerfile \
infrastructure/environments/attendance/Dockerfile \
infrastructure/environments/course-management/Dockerfile \
infrastructure/environments/payment/Dockerfile \
infrastructure/environments/credentials/Dockerfile \
infrastructure/environments/api-gateway/Dockerfile \
infrastructure/environments/frontend/Dockerfile \
infrastructure/environments/rabbitmq/Dockerfile \
infrastructure/environments/tls-init/Dockerfile; do
echo "Linting $dockerfile"
docker run --rm -i hadolint/hadolint@sha256:30a8fd2e785ab6176eed53f74769e04f125afb2f74a6c52aef7d463583b6d45e < "$dockerfile"
done

build-backend:
needs: changes
if: ${{ needs.changes.outputs.backends != '[]' }}
Expand All @@ -88,14 +109,33 @@ jobs:
nuget-${{ runner.os }}-

- name: Restore
run: dotnet restore apps/${{ matrix.service }}/Backend/Backend.csproj
run: dotnet restore apps/${{ matrix.service }}/Backend/Backend.csproj --locked-mode

- name: Verify formatting (.editorconfig + analyzers)
run: dotnet format apps/${{ matrix.service }}/Backend/Backend.csproj --verify-no-changes --no-restore

- name: Build (warnings as errors → SonarAnalyzer strict)
run: dotnet build apps/${{ matrix.service }}/Backend/Backend.csproj -c Release --no-restore -p:TreatWarningsAsErrors=true

- name: Generate SBOM
run: |
dotnet tool install --global Microsoft.Sbom.DotNet
export PATH="$HOME/.dotnet/tools:$PATH"
sbom-tool generate \
-b apps/${{ matrix.service }}/Backend \
-bc apps/${{ matrix.service }}/Backend \
-pn DAMA.${{ matrix.service }} \
-pv ${{ github.sha }} \
-ps DAMA-Software \
-nsb https://github.com/JCarlosHidalgo/DAMA
continue-on-error: true

- uses: actions/upload-artifact@v4
if: always()
with:
name: sbom-${{ matrix.service }}
path: apps/${{ matrix.service }}/Backend/_manifest/spdx_2.2/

build-frontend:
needs: changes
if: ${{ needs.changes.outputs.frontend == 'true' }}
Expand All @@ -106,7 +146,7 @@ jobs:
steps:
- uses: actions/checkout@v5

- uses: oven-sh/setup-bun@v2
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: '1.3.10'

Expand Down Expand Up @@ -238,7 +278,7 @@ jobs:
steps:
- uses: actions/checkout@v5

- uses: oven-sh/setup-bun@v2
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: '1.3.10'

Expand All @@ -256,7 +296,7 @@ jobs:
run: bun run test:coverage:gate

ci-gate:
needs: [build-backend, build-frontend, test-backend, test-frontend]
needs: [build-backend, build-frontend, test-backend, test-frontend, lint-dockerfiles]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
Expand All @@ -268,6 +308,7 @@ jobs:
[build-frontend]='${{ needs.build-frontend.result }}'
[test-backend]='${{ needs.test-backend.result }}'
[test-frontend]='${{ needs.test-frontend.result }}'
[lint-dockerfiles]='${{ needs.lint-dockerfiles.result }}'
)
failed=0
for job in "${!results[@]}"; do
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ jobs:
alpine sh -c "cp -r /data/. /out/ 2>/dev/null || true"
done

- name: Generate checksums
run: |
for svc in auth payment course-management attendance frontend; do
find "site/tests/$svc" -type f | sort | \
xargs sha256sum > "site/tests/$svc/checksums.sha256"
done

- uses: actions/upload-artifact@v4
with:
name: tests-html
Expand Down
1 change: 1 addition & 0 deletions apps/Attendance/Backend/Backend.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading
Loading