Create config_guardrails.yml
This commit is contained in:
222
.github/workflows/config_guardrails.yml
vendored
Normal file
222
.github/workflows/config_guardrails.yml
vendored
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Copyright (C) 2025 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
#
|
||||||
|
# This file is part of a Moko Consulting project.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# FILE INFORMATION
|
||||||
|
# DEFGROUP: GitHub.Workflow
|
||||||
|
# INGROUP: MokoStandards.Validation
|
||||||
|
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||||
|
# PATH: /.github/workflows/config_guardrails.yml
|
||||||
|
# VERSION: 03.05.00
|
||||||
|
# BRIEF: Validate that required repository secrets and variables exist for workflows and scripts.
|
||||||
|
# NOTE: Secrets are never printed. This workflow only verifies presence and emits an audit JSON report.
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
name: Config Guardrails (secrets and vars)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
profile:
|
||||||
|
description: "Which configuration profile to validate. release checks SFTP variables used by release_pipeline. scripts checks baseline script prerequisites. all runs both."
|
||||||
|
required: true
|
||||||
|
default: all
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- all
|
||||||
|
- release
|
||||||
|
- scripts
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- ".github/workflows/**"
|
||||||
|
- "scripts/**"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
guardrails:
|
||||||
|
name: Guardrails
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Validate required repository secrets and variables
|
||||||
|
env:
|
||||||
|
PROFILE: ${{ github.event.inputs.profile || 'all' }}
|
||||||
|
|
||||||
|
# Release pipeline SFTP configuration (secrets + vars)
|
||||||
|
FTP_HOST: ${{ secrets.FTP_HOST }}
|
||||||
|
FTP_USER: ${{ secrets.FTP_USER }}
|
||||||
|
FTP_KEY: ${{ secrets.FTP_KEY }}
|
||||||
|
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
|
||||||
|
FTP_PATH: ${{ secrets.FTP_PATH }}
|
||||||
|
FTP_PROTOCOL: ${{ secrets.FTP_PROTOCOL }}
|
||||||
|
FTP_PORT: ${{ secrets.FTP_PORT }}
|
||||||
|
FTP_PATH_SUFFIX: ${{ vars.FTP_PATH_SUFFIX }}
|
||||||
|
|
||||||
|
run: |
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
profile="${PROFILE}"
|
||||||
|
|
||||||
|
# Centralized checklist.
|
||||||
|
required_release_secrets=(
|
||||||
|
"FTP_HOST"
|
||||||
|
"FTP_USER"
|
||||||
|
"FTP_KEY"
|
||||||
|
"FTP_PATH"
|
||||||
|
)
|
||||||
|
|
||||||
|
optional_release=(
|
||||||
|
"FTP_PASSWORD" # Only needed for encrypted PPK conversion
|
||||||
|
"FTP_PROTOCOL" # Defaults to sftp in pipelines
|
||||||
|
"FTP_PORT" # Defaults to provider default
|
||||||
|
"FTP_PATH_SUFFIX" # Variable, optional
|
||||||
|
)
|
||||||
|
|
||||||
|
required_script_files=(
|
||||||
|
"scripts/verify_manifest.sh"
|
||||||
|
"scripts/validate_xml_wellformed.sh"
|
||||||
|
"scripts/validate_changelog.sh"
|
||||||
|
"scripts/validate_tabs.sh"
|
||||||
|
"scripts/validate_paths.sh"
|
||||||
|
"scripts/validate_version_alignment.sh"
|
||||||
|
"scripts/validate_language_structure.sh"
|
||||||
|
"scripts/validate_php_syntax.sh"
|
||||||
|
"scripts/validate_no_secrets.sh"
|
||||||
|
"scripts/validate_license_headers.sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
missing=()
|
||||||
|
missing_optional=()
|
||||||
|
missing_files=()
|
||||||
|
|
||||||
|
check_release() {
|
||||||
|
for k in "${required_release_secrets[@]}"; do
|
||||||
|
v="${!k:-}"
|
||||||
|
if [ -z "${v}" ]; then
|
||||||
|
missing+=("${k}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Optional configuration.
|
||||||
|
for k in "${optional_release[@]}"; do
|
||||||
|
v="${!k:-}"
|
||||||
|
if [ -z "${v}" ]; then
|
||||||
|
missing_optional+=("${k}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Protocol sanity if provided.
|
||||||
|
proto="${FTP_PROTOCOL:-sftp}"
|
||||||
|
if [ -n "${FTP_PROTOCOL:-}" ] && [ "${proto}" != "sftp" ]; then
|
||||||
|
missing+=("FTP_PROTOCOL_INVALID")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Key format guardrail (do not print key).
|
||||||
|
if [ -n "${FTP_KEY:-}" ]; then
|
||||||
|
first_line="$(printf '%s' "${FTP_KEY}" | head -n 1 || true)"
|
||||||
|
if printf '%s' "${first_line}" | grep -q '^PuTTY-User-Key-File-'; then
|
||||||
|
key_format="ppk"
|
||||||
|
elif printf '%s' "${first_line}" | grep -q '^-----BEGIN '; then
|
||||||
|
key_format="openssh"
|
||||||
|
else
|
||||||
|
key_format="unknown"
|
||||||
|
missing+=("FTP_KEY_FORMAT")
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
key_format="missing"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "KEY_FORMAT=${key_format}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_scripts() {
|
||||||
|
for f in "${required_script_files[@]}"; do
|
||||||
|
if [ ! -f "${f}" ]; then
|
||||||
|
missing_files+=("${f}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Tooling expectations: scripts may rely on php and xmllint.
|
||||||
|
# Do not fail on tooling here; CI runners can install dependencies.
|
||||||
|
# Still report as guardrail visibility.
|
||||||
|
tool_missing=()
|
||||||
|
command -v php >/dev/null 2>&1 || tool_missing+=("php")
|
||||||
|
command -v xmllint >/dev/null 2>&1 || tool_missing+=("xmllint")
|
||||||
|
|
||||||
|
if [ "${#tool_missing[@]}" -gt 0 ]; then
|
||||||
|
echo "WARN: Missing tools on runner (install in workflow when required): ${tool_missing[*]}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${profile}" in
|
||||||
|
release)
|
||||||
|
check_release
|
||||||
|
;;
|
||||||
|
scripts)
|
||||||
|
check_scripts
|
||||||
|
;;
|
||||||
|
all)
|
||||||
|
check_release
|
||||||
|
check_scripts
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Emit report.
|
||||||
|
{
|
||||||
|
echo "### Config guardrails report (JSON)"
|
||||||
|
echo "```json"
|
||||||
|
printf '{"repository":"%s","profile":"%s","missing_required":[' "${GITHUB_REPOSITORY}" "${profile}"
|
||||||
|
sep=""
|
||||||
|
for m in "${missing[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${m}"
|
||||||
|
sep=","
|
||||||
|
done
|
||||||
|
printf '],"missing_optional":['
|
||||||
|
sep=""
|
||||||
|
for m in "${missing_optional[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${m}"
|
||||||
|
sep=","
|
||||||
|
done
|
||||||
|
printf '],"missing_script_files":['
|
||||||
|
sep=""
|
||||||
|
for m in "${missing_files[@]}"; do
|
||||||
|
printf '%s"%s"' "${sep}" "${m}"
|
||||||
|
sep=","
|
||||||
|
done
|
||||||
|
printf ']}'
|
||||||
|
echo
|
||||||
|
echo "```"
|
||||||
|
} >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
|
||||||
|
# Fail the workflow if required items are missing.
|
||||||
|
if [ "${#missing[@]}" -gt 0 ] || [ "${#missing_files[@]}" -gt 0 ]; then
|
||||||
|
echo "ERROR: Config guardrails failed. Missing required configuration or script files." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user