Files
lint-enforcement-v2/.gitea/workflows/pr-lint-gate.yml
Scaffolder abffd7aeb7
All checks were successful
Build and Publish TechDocs / build-and-publish (push) Successful in 1m3s
initial commit
Change-Id: I3194558e1a840334641aff81960492489f171232
2026-07-08 09:13:14 +00:00

220 lines
6.3 KiB
YAML

name: PR Lint and Validation Gate
on:
pull_request:
branches: [ "main" ]
workflow_dispatch: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
yaml-and-whitespace:
name: YAML and Whitespace
runs-on: ubuntu-latest
outputs:
elapsed_seconds: ${{ steps.elapsed.outputs.seconds }}
steps:
- name: Start timer
run: echo "START_TS=$(date +%s)" >> "$GITHUB_ENV"
- name: Checkout
uses: actions/checkout@v4
- name: Install yamllint
run: |
python3 -m pip install --upgrade pip
python3 -m pip install yamllint
- name: Run yamllint
run: |
yamllint -d "{extends: default, rules: {line-length: {max: 180}, truthy: disable}}" .
- name: Check trailing whitespace
run: |
if git ls-files -z | xargs -0 -I{} grep -nH -E "[[:blank:]]+$" "{}" \
--exclude="*.md" --exclude="*.svg"; then
echo "Trailing whitespace found"
exit 1
fi
- name: Capture duration
id: elapsed
if: always()
run: |
end_ts=$(date +%s)
start_ts=${START_TS:-$end_ts}
echo "seconds=$((end_ts - start_ts))" >> "$GITHUB_OUTPUT"
helm-lint:
name: Helm Lint
runs-on: ubuntu-latest
outputs:
elapsed_seconds: ${{ steps.elapsed.outputs.seconds }}
steps:
- name: Start timer
run: echo "START_TS=$(date +%s)" >> "$GITHUB_ENV"
- name: Checkout
uses: actions/checkout@v4
- name: Install Helm
uses: azure/setup-helm@v4
- name: Lint all charts
run: |
mapfile -t charts < <(find . -type f -name Chart.yaml -print)
if [ -z "${charts[0]:-}" ]; then
echo "No Helm charts found; skipping"
exit 0
fi
failed=0
for chart in "${charts[@]}"; do
chart_dir="$(dirname "$chart")"
echo "Linting ${chart_dir}"
if ! helm lint "$chart_dir"; then
failed=1
fi
done
exit $failed
- name: Capture duration
id: elapsed
if: always()
run: |
end_ts=$(date +%s)
start_ts=${START_TS:-$end_ts}
echo "seconds=$((end_ts - start_ts))" >> "$GITHUB_OUTPUT"
terraform-lint:
name: Terraform Validate and TFLint
runs-on: ubuntu-latest
outputs:
elapsed_seconds: ${{ steps.elapsed.outputs.seconds }}
steps:
- name: Start timer
run: echo "START_TS=$(date +%s)" >> "$GITHUB_ENV"
- name: Checkout
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Install TFLint
run: |
curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
- name: Validate Terraform directories
run: |
mapfile -t tf_dirs < <(find . -type f -name "*.tf" -exec dirname {} \; | sort -u)
if [ -z "${tf_dirs[0]:-}" ]; then
echo "No Terraform files found; skipping"
exit 0
fi
failed=0
for dir in "${tf_dirs[@]}"; do
echo "Validating ${dir}"
(
cd "$dir"
terraform init -backend=false -input=false -no-color
terraform validate -no-color
tflint --chdir .
) || failed=1
done
exit $failed
- name: Capture duration
id: elapsed
if: always()
run: |
end_ts=$(date +%s)
start_ts=${START_TS:-$end_ts}
echo "seconds=$((end_ts - start_ts))" >> "$GITHUB_OUTPUT"
policy-and-deps:
name: Policy and Dependency Scan
runs-on: ubuntu-latest
outputs:
elapsed_seconds: ${{ steps.elapsed.outputs.seconds }}
steps:
- name: Start timer
run: echo "START_TS=$(date +%s)" >> "$GITHUB_ENV"
- name: Checkout
uses: actions/checkout@v4
- name: Install Checkov
run: |
python3 -m pip install --upgrade pip
python3 -m pip install checkov
- name: Run Checkov (Kubernetes)
run: |
checkov -d . --framework kubernetes --quiet
- name: npm audit (if package.json exists)
run: |
if [ -f package.json ]; then
npm install --no-audit --no-fund
npm audit --audit-level=high
else
echo "No package.json found; skipping npm audit"
fi
- name: Maven dependency-check (if pom.xml exists)
run: |
if [ -f pom.xml ]; then
mvn -B org.owasp:dependency-check-maven:check
else
echo "No pom.xml found; skipping Maven dependency-check"
fi
- name: Capture duration
id: elapsed
if: always()
run: |
end_ts=$(date +%s)
start_ts=${START_TS:-$end_ts}
echo "seconds=$((end_ts - start_ts))" >> "$GITHUB_OUTPUT"
runtime-slo:
name: Runtime SLO (< 3 min)
if: always()
needs:
- yaml-and-whitespace
- helm-lint
- terraform-lint
- policy-and-deps
runs-on: ubuntu-latest
steps:
- name: Enforce suite runtime budget
run: |
y=${{ needs.yaml-and-whitespace.outputs.elapsed_seconds || 0 }}
h=${{ needs.helm-lint.outputs.elapsed_seconds || 0 }}
t=${{ needs.terraform-lint.outputs.elapsed_seconds || 0 }}
p=${{ needs.policy-and-deps.outputs.elapsed_seconds || 0 }}
# Jobs run in parallel; full-suite wall-clock is approximated by max(job runtimes).
suite=$y
[ $h -gt $suite ] && suite=$h
[ $t -gt $suite ] && suite=$t
[ $p -gt $suite ] && suite=$p
echo "## PR Lint Gate Runtime" >> "$GITHUB_STEP_SUMMARY"
echo "- YAML and Whitespace: ${y}s" >> "$GITHUB_STEP_SUMMARY"
echo "- Helm Lint: ${h}s" >> "$GITHUB_STEP_SUMMARY"
echo "- Terraform Validate and TFLint: ${t}s" >> "$GITHUB_STEP_SUMMARY"
echo "- Policy and Dependency Scan: ${p}s" >> "$GITHUB_STEP_SUMMARY"
echo "- Full suite (parallel max): ${suite}s" >> "$GITHUB_STEP_SUMMARY"
if [ $suite -gt 180 ]; then
echo "Runtime SLO exceeded: ${suite}s > 180s"
exit 1
fi