mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-28 11:25:00 +00:00
76 lines
3.6 KiB
Bash
Executable file
76 lines
3.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
SECURITY_WORKFLOW="$REPO_ROOT/.github/workflows/security.yml"
|
|
PR_SCRIPTS_WORKFLOW="$REPO_ROOT/.github/workflows/pr-scripts.yml"
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
assert_pr_workflow_hardened() {
|
|
local workflow="$1"
|
|
grep -Eq '^permissions:[[:space:]]*$' "$workflow" \
|
|
|| fail "$workflow must declare top-level permissions"
|
|
grep -Eq '^[[:space:]]+contents:[[:space:]]+read[[:space:]]*$' "$workflow" \
|
|
|| fail "$workflow GITHUB_TOKEN permissions must include contents: read"
|
|
grep -Fq 'persist-credentials: false' "$workflow" \
|
|
|| fail "$workflow checkout steps must not persist credentials"
|
|
}
|
|
|
|
[[ -f "$SECURITY_WORKFLOW" ]] || fail ".github/workflows/security.yml is required"
|
|
|
|
assert_pr_workflow_hardened "$REPO_ROOT/.github/workflows/pr-cli.yml"
|
|
assert_pr_workflow_hardened "$REPO_ROOT/.github/workflows/pr-e2e.yml"
|
|
assert_pr_workflow_hardened "$REPO_ROOT/.github/workflows/pr-tests.yml"
|
|
assert_pr_workflow_hardened "$PR_SCRIPTS_WORKFLOW"
|
|
assert_pr_workflow_hardened "$SECURITY_WORKFLOW"
|
|
|
|
grep -Fq 'actions/dependency-review-action' "$SECURITY_WORKFLOW" \
|
|
|| fail "security workflow must run dependency review"
|
|
grep -Fq 'github/codeql-action/init' "$SECURITY_WORKFLOW" \
|
|
|| fail "security workflow must initialize CodeQL"
|
|
grep -Fq 'cd server && ./mvnw -q -DskipTests package' "$SECURITY_WORKFLOW" \
|
|
|| fail "security workflow must build Java with the server Maven wrapper"
|
|
grep -Fq 'security-events: write' "$SECURITY_WORKFLOW" \
|
|
|| fail "security workflow must grant SARIF upload permission"
|
|
|
|
python_source="$(find "$REPO_ROOT" \
|
|
\( -path "$REPO_ROOT/.git" -o -path '*/node_modules' -o -path '*/.venv' \) -prune -o \
|
|
-type f -name '*.py' -print -quit)"
|
|
if [[ -n "$python_source" ]]; then
|
|
grep -Fq 'language: python' "$SECURITY_WORKFLOW" \
|
|
|| fail "security workflow must run Python CodeQL when Python source exists"
|
|
else
|
|
! grep -Fq 'language: python' "$SECURITY_WORKFLOW" \
|
|
|| fail "security workflow must not run Python CodeQL without Python source"
|
|
fi
|
|
|
|
grep -Fq '.github/workflows/security.yml' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when security workflow changes"
|
|
grep -Fq '.github/workflows/pr-cli.yml' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when PR CLI workflow changes"
|
|
grep -Fq '.github/workflows/pr-e2e.yml' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when PR E2E workflow changes"
|
|
grep -Fq '.github/workflows/pr-tests.yml' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when PR Tests workflow changes"
|
|
grep -Fq "'**/*.py'" "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when Python source changes"
|
|
grep -Fq '.env.release.example' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when release env example changes"
|
|
grep -Fq '.env.release.draft' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when release env draft changes"
|
|
grep -Fq 'compose.release.yml' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run when release compose changes"
|
|
grep -Fq 'bash scripts/tests/validate-release-config-test.sh' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run validate-release-config-test"
|
|
grep -Fq 'bash scripts/tests/runtime-secret-test.sh' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run runtime-secret-test"
|
|
grep -Fq 'bash scripts/tests/dev-web-host-test.sh' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run dev-web-host-test"
|
|
grep -Fq 'bash scripts/tests/workflow-security-test.sh' "$PR_SCRIPTS_WORKFLOW" \
|
|
|| fail "pr-scripts must run workflow-security-test"
|
|
|
|
echo "workflow-security-test passed"
|