Skip to content

Move aucore to AU PS generator 1.0.2 #125

Move aucore to AU PS generator 1.0.2

Move aucore to AU PS generator 1.0.2 #125

name: Validate Configuration
on:
pull_request:
paths:
- 'module-config/**'
- 'terraform/**'
- 'scripts/test_consent_default_readonly.js'
- '.github/workflows/validate-config.yml'
push:
branches:
- main
paths:
- 'module-config/**'
- 'terraform/**'
- 'scripts/test_consent_default_readonly.js'
- '.github/workflows/validate-config.yml'
# These jobs use NO secrets, so they are safe to run on PRs from forks (community
# contributions). Runner selection enforces one invariant: untrusted fork code
# must never execute on the self-hosted arc-runner-set. So a fork PR always runs
# on a GitHub-hosted runner (free for public repos), while same-repo PRs and
# pushes use vars.CI_RUNNER (the self-hosted runner) if set. Anything needing
# secrets or live-server/AWS access is gated elsewhere behind maintainer-triggered
# workflows, never on fork PR events.
jobs:
validate-yaml:
name: Validate YAML Configuration
runs-on: ${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'ubuntu-latest' }}
container:
image: python:3.12-slim
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: pip install -r scripts/requirements.txt
- name: Validate YAML files
run: |
yamllint -d "{extends: default, rules: {line-length: {max: 200}, indentation: {spaces: 2}}}" module-config/*.yaml || true
echo "✅ YAML syntax validation complete"
- name: Check for common issues
run: |
echo "Checking for common configuration issues..."
# Every module-config file referenced by terraform/main.tf must exist.
# Covers the package specs and the scripts mapped into config_seeding
# (smart-post-authorize.js, consent-default-readonly.js): a module that
# points at a missing script file fails at module startup, not at apply.
#
# Not a `while read` over a pipe: that runs the loop in a subshell, so
# its exit only leaves the subshell and the step still passes.
echo "📦 Verifying module-config file references..."
missing=0
for filepath in $(grep -oE '\.\./module-config/[A-Za-z0-9._/-]+' terraform/main.tf | sed 's|\.\./||' | sort -u); do
if [ -f "$filepath" ]; then
echo " ✅ Found: $filepath"
else
echo " ❌ Missing: $filepath"
missing=1
fi
done
# Every script referenced by a consent_service.script.file or
# post_authorize_script.file classpath must also be mapped in by
# terraform, or the node boots pointing at a file that is not there.
echo "📜 Verifying config_seeding script references..."
for script in $(grep -hoE 'classpath:/?config_seeding/[A-Za-z0-9._-]+\.js([^a-z]|$)' module-config/*.yaml | sed -e 's|.*/||' -e 's|\.js.*|.js|' | sort -u); do
if grep -q "module-config/$script" terraform/main.tf; then
echo " ✅ Mapped by terraform: $script"
else
echo " ❌ Referenced in module config but not mapped in terraform/main.tf: $script"
missing=1
fi
done
exit $missing
validate-consent-script:
name: Test Consent Service Script
# The consent service runs in front of every REST request on the node, so
# its decision matrix is unit tested before it can be deployed. Node 24 is
# the current LTS; the test has no dependencies.
runs-on: ${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'ubuntu-latest' }}
container:
image: node:24-slim
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run consent service tests
run: node scripts/test_consent_default_readonly.js
validate-terraform:
name: Validate Terraform
# Fork-safe: no backend, no credentials, no PR comment (fork tokens are
# read-only). Contributors see the result via the check status.
runs-on: ${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'ubuntu-latest' }}
# Run in a Debian container that we install Terraform into, rather than the
# setup-terraform action: this works identically on GitHub-hosted runners and
# on the self-hosted arc-runner-set (whose base image has no Terraform binary).
container:
image: debian:bookworm-slim
defaults:
run:
working-directory: terraform
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Terraform
run: |
apt-get update
# git is required by terraform to fetch the git:: sourced module
apt-get install -y --no-install-recommends curl unzip ca-certificates git
curl -fsSL "https://releases.hashicorp.com/terraform/1.15.6/terraform_1.15.6_linux_amd64.zip" -o /tmp/terraform.zip
unzip -o /tmp/terraform.zip -d /usr/local/bin
terraform version
- name: Terraform Format Check
run: terraform fmt -check -recursive
continue-on-error: true
- name: Terraform Init (no backend)
run: terraform init -backend=false
- name: Terraform Validate
run: terraform validate
validate-packages:
name: Validate FHIR Packages
runs-on: ${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'ubuntu-latest' }}
container:
image: python:3.12-slim
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
apt-get update
apt-get install -y jq
- name: Validate JSON syntax
run: |
echo "Validating package JSON files..."
find module-config/packages -name "*.json" -type f | while read file; do
echo "Checking $file..."
if jq empty "$file" 2>/dev/null; then
echo " ✅ Valid JSON: $file"
else
echo " ❌ Invalid JSON: $file"
exit 1
fi
done
- name: Check package structure
run: |
echo "Checking package file structure..."
find module-config/packages -name "package-*.json" -type f | while read file; do
# Check for required fields
if jq -e '.name and .version' "$file" >/dev/null 2>&1; then
name=$(jq -r '.name' "$file")
version=$(jq -r '.version' "$file")
echo " ✅ $file: $name@$version"
else
echo " ⚠️ $file: Missing name or version field"
fi
done
security-scan:
name: Security Scan
runs-on: ${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'ubuntu-latest' }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy security scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'config'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
continue-on-error: true
- name: Check for sensitive data
run: |
echo "Scanning for potential secrets..."
# Check for common patterns that might be secrets
if grep -r "password.*=.*['\"].*['\"]" --include="*.tf" --include="*.yaml" --exclude-dir=".git" .; then
echo "⚠️ Warning: Found potential hardcoded passwords"
fi
if grep -r "secret.*=.*['\"].*['\"]" --include="*.tf" --include="*.yaml" --exclude-dir=".git" .; then
echo "⚠️ Warning: Found potential hardcoded secrets"
fi
echo "✅ Security scan complete"