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
31 changes: 28 additions & 3 deletions .github/workflows/validate-branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ jobs:
node-version: '22'
- name: Ensure base commit present
run: git fetch --no-tags origin "$(node -e "console.log(require('./course-build/manifest.json').base.sha)")" || true
- name: Configure git identity (for git am)
run: |
git config user.name "acc-course-bot"
git config user.email "acc-course-bot@users.noreply.github.com"
- name: Deterministic delta check (trees, assets, ancestry)
run: node course-build/scripts/build-branches.mjs --check
- name: Self-test (classification + path detection)
Expand All @@ -69,6 +73,8 @@ jobs:
echo "Buildable: $branches"

# Secret scan of the delta store and everything the built branches would contain.
# Runs the gitleaks OSS binary directly rather than gitleaks/gitleaks-action@v2,
# which requires a paid GITLEAKS_LICENSE secret for organization repositories.
secret-scan:
runs-on: ubuntu-latest
steps:
Expand All @@ -77,10 +83,21 @@ jobs:
fetch-depth: 0
ref: ${{ inputs.ref || github.ref }}
- name: gitleaks (delta store + course-build)
uses: gitleaks/gitleaks-action@v2
env:
GITLEAKS_ENABLE_UPLOAD_ARTIFACT: 'false'
GITLEAKS_ENABLE_SUMMARY: 'true'
GITLEAKS_VERSION: '8.30.1'
# SHA256 of gitleaks_${VERSION}_linux_x64.tar.gz from the upstream
# gitleaks_${VERSION}_checksums.txt release asset. Bump both together on upgrade.
GITLEAKS_SHA256: '551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb'
run: |
set -euo pipefail
tarball="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${tarball}" -o /tmp/gitleaks.tar.gz
# Verify integrity before extracting/executing (pinned supply-chain check).
echo "${GITLEAKS_SHA256} /tmp/gitleaks.tar.gz" | sha256sum -c -
tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks
/tmp/gitleaks version
# Scan the full commit history (fetch-depth: 0). Exits non-zero on any finding.
/tmp/gitleaks git . --redact --verbose

# Heavy gate: build each buildable learner branch from deltas and run the suites
# that exist in that cumulative state (web / .NET / Java / Python / Playwright),
Expand Down Expand Up @@ -117,6 +134,14 @@ jobs:
run: |
git config user.name "acc-course-bot"
git config user.email "acc-course-bot@users.noreply.github.com"
- name: Provision /data volume for service DBs
# The services default their SQLite databases to /data/<svc>.db (overridable via
# *_DB_PATH), where /data is a mounted volume under docker compose. Bare `mvn test`
# / `dotnet test` / `pytest` on the runner have no such volume, so the Spring
# services abort at startup with "path to '/data/...': '/data' does not exist".
# Create it writable to mirror the runtime contract without touching learner-branch
# app files (which would change the delta-store tree SHAs verify-deltas asserts).
run: sudo mkdir -p /data && sudo chmod 777 /data
- name: Build + validate ${{ matrix.start_branch }}
run: bash course-build/scripts/validate-branch.sh "${{ matrix.start_branch }}"
env:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ index 0000000..dee69bc
+ test('asset detail page shows an accessible QR code', async ({ page }) => {
+ // Land on the assets list and open the first asset's detail page.
+ await page.goto('/assets');
+ const firstAsset = page.locator('a[href^="/assets/"]').first();
+ const firstAsset = page.locator('tbody a[href^="/assets/"]').first();
+ await firstAsset.click();
+
+ // The QR card heading and the accessible QR image are present.
Expand Down
4 changes: 2 additions & 2 deletions course-build/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"patches": [
"0001-feat-module-05-add-QR-barcode-support-QA-agent-resea.patch"
],
"expectedTreeSha": "ba8126ae1414dbcc25cfed544071c848e33fcf1c",
"expectedTreeSha": "848992615da50a401c9db17da55840e5f6d93e67",
"expectedAssets": [
".github/agents/qa.agent.md",
"reports/qr-code-research.md",
Expand All @@ -156,7 +156,7 @@
"patches": [
"0001-feat-module-06-modernize-audit-svc-auth-svc-to-Sprin.patch"
],
"expectedTreeSha": "54a47a032fe12e6f9496040d93c6ed123c28f8b3",
"expectedTreeSha": "cb9a6a19492fa0b7d285685e875f1f03acfc27f7",
"expectedAssets": [
".github/lsp.json",
".github/agents/java-migrator.agent.md",
Expand Down
14 changes: 12 additions & 2 deletions course-build/scripts/validate-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,18 @@ echo "==> Java services build (all on Java 21; audit/auth target Java 17 bytecod
echo "==> Python services install + pytest"
for svc in reporting-svc notifications-svc; do
if [ -f "services/$svc/pyproject.toml" ]; then
pip install -e "services/$svc"
if [ -d "services/$svc/tests" ]; then ( cd "services/$svc" && python -m pytest -q ); fi
# Early modules ship a tests/ dir containing only a README; real test files
# (test_*.py / *_test.py) appear from M03 onward. Only run pytest when they exist,
# otherwise just verify the service is installable.
if ls "services/$svc"/tests/test_*.py "services/$svc"/tests/*_test.py >/dev/null 2>&1; then
# Install the dev extra (pins pytest/pytest-asyncio) when declared, and guarantee
# pytest is importable so `python -m pytest` never fails with "No module named pytest".
pip install -e "services/$svc[dev]"
python -c "import pytest" 2>/dev/null || pip install pytest pytest-asyncio
( cd "services/$svc" && python -m pytest -q )
else
pip install -e "services/$svc"
fi
fi
done

Expand Down
Loading