fix: align scoped coverage and test timeout

This commit is contained in:
chichuan
2026-07-30 20:06:24 +08:00
parent 3bdc30badb
commit 21144af79b
4 changed files with 166 additions and 3 deletions
+7 -1
View File
@@ -438,7 +438,7 @@ jobs:
needs: lint
if: ${{ needs.lint.outputs.changelog_only != 'true' && needs.lint.outputs.docs_only != 'true' && needs.lint.outputs.full_suite != 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 20
steps:
- name: Check out repository
uses: actions/checkout@v4
@@ -1160,14 +1160,20 @@ jobs:
- name: Enforce coverage gate
if: needs.lint.outputs.changelog_only != 'true' && needs.lint.outputs.docs_only != 'true'
env:
FULL_SUITE: ${{ needs.lint.outputs.full_suite }}
COVERAGE_TARGET: "100"
COVERAGE_ENFORCE_OVERALL: "false"
COVERAGE_OVERALL_TOLERANCE: "0"
run: |
policy_profile=coverage-policy.txt
if [ "$FULL_SUITE" != true ]; then
policy_profile=
fi
additional_profile=
if [ -f coverage-shortcut.txt ]; then
additional_profile=coverage-shortcut.txt
fi
COVERAGE_DIFF_PROFILE="$policy_profile" \
COVERAGE_ADDITIONAL_DIFF_PROFILE="$additional_profile" \
make coverage-gate BASE_REF="$COVERAGE_BASE_REF"
+4 -2
View File
@@ -6,7 +6,7 @@ BASE_REF=""
OVERALL_PROFILE="coverage.txt"
ADDITIONAL_DIFF_PROFILE="${COVERAGE_ADDITIONAL_DIFF_PROFILE:-${COVERAGE_ADDITIONAL_PROFILE:-}}"
BASELINE_PROFILE="coverage-base.txt"
DIFF_PROFILE="coverage-policy.txt"
DIFF_PROFILE="${COVERAGE_DIFF_PROFILE-coverage-policy.txt}"
TARGET="${COVERAGE_TARGET:-100}"
OVERALL_TOLERANCE="${COVERAGE_OVERALL_TOLERANCE:-0}"
ENFORCE_OVERALL="${COVERAGE_ENFORCE_OVERALL:-false}"
@@ -77,13 +77,15 @@ go build -o "$CHECKER" ./scripts/policy/coverage-gate
module="$(go list -m -f '{{.Path}}')"
set -- "$CHECKER" \
--diff-profile "$DIFF_PROFILE" \
--base-ref "$BASE_REF" \
--module "$module" \
--overall-tolerance "$OVERALL_TOLERANCE" \
--target "$TARGET" \
--enforce-overall-target="$ENFORCE_OVERALL"
if [ -n "$DIFF_PROFILE" ]; then
set -- "$@" --diff-profile "$DIFF_PROFILE"
fi
if [ "$CHANGED_ONLY" = "true" ]; then
set -- "$@" --changed-only
else
+35
View File
@@ -514,6 +514,35 @@ func TestChangelogPRFastPathWorkflowContract(t *testing.T) {
t.Error("Code Admission must not suppress required contexts with paths-ignore")
}
focusedStart := strings.Index(admission, "\n test-focused:\n")
focusedEnd := strings.Index(admission, "\n test-race:\n")
if focusedStart < 0 || focusedEnd <= focusedStart {
t.Fatal("Code Admission workflow missing focused test job boundaries")
}
focusedJob := admission[focusedStart:focusedEnd]
if !strings.Contains(focusedJob, "timeout-minutes: 20") {
t.Error("focused test job must allow the scoped race suite up to 20 minutes")
}
coverageStart := strings.Index(admission, "\n coverage:\n")
coverageEnd := strings.Index(admission, "\n policy:\n")
if coverageStart < 0 || coverageEnd <= coverageStart {
t.Fatal("Code Admission workflow missing coverage job boundaries")
}
coverageJob := admission[coverageStart:coverageEnd]
for _, want := range []string{
`FULL_SUITE: ${{ needs.lint.outputs.full_suite }}`,
"policy_profile=coverage-policy.txt\n" +
` if [ "$FULL_SUITE" != true ]; then` + "\n" +
" policy_profile=\n" +
" fi",
`COVERAGE_DIFF_PROFILE="$policy_profile"`,
} {
if !strings.Contains(coverageJob, want) {
t.Errorf("Code Admission workflow missing scoped coverage contract %q", want)
}
}
notification := readWorkflow(".github/workflows/notify-wukong.yml")
if !strings.Contains(notification, "- CI") {
t.Error("Wukong notification must follow the renamed CI workflow")
@@ -529,6 +558,12 @@ func TestChangelogPRFastPathWorkflowContract(t *testing.T) {
if !strings.Contains(coverageGate, `OVERALL_TOLERANCE="${COVERAGE_OVERALL_TOLERANCE:-0}"`) {
t.Error("coverage gate must reject any reported overall regression")
}
if !strings.Contains(coverageGate, `DIFF_PROFILE="${COVERAGE_DIFF_PROFILE-coverage-policy.txt}"`) {
t.Error("coverage gate must allow scoped CI to explicitly omit the supporting policy profile")
}
if !strings.Contains(coverageGate, `if [ -n "$DIFF_PROFILE" ]; then`) {
t.Error("coverage gate must add the supporting policy profile only when configured")
}
if !strings.Contains(coverageGate, `--baseline-profile "$BASELINE_PROFILE"`) {
t.Error("coverage gate must evaluate the merge-base profile with the candidate checker")
}
@@ -0,0 +1,120 @@
package scripts_test
import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
func TestCoverageGatePolicyProfileCanBeExplicitlyOmitted(t *testing.T) {
root, err := filepath.Abs(filepath.Join("..", ".."))
if err != nil {
t.Fatalf("Abs(repo root) error = %v", err)
}
binDir := t.TempDir()
fakeGoPath := filepath.Join(binDir, "go")
const fakeGo = `#!/bin/sh
set -eu
case "$1" in
build)
shift
output=
while [ "$#" -gt 0 ]; do
case "$1" in
-o)
output="$2"
shift 2
;;
*)
shift
;;
esac
done
cat > "$output" <<'EOF'
#!/bin/sh
printf '%s\n' "$@" > "$COVERAGE_ARGS_LOG"
EOF
chmod +x "$output"
;;
list)
printf '%s\n' "example.com/coverage-fixture"
;;
*)
printf 'unexpected fake go command: %s\n' "$1" >&2
exit 2
;;
esac
`
if err := os.WriteFile(fakeGoPath, []byte(fakeGo), 0o755); err != nil {
t.Fatalf("WriteFile(fake go) error = %v", err)
}
baseEnv := make([]string, 0, len(os.Environ())+2)
for _, value := range os.Environ() {
if strings.HasPrefix(value, "PATH=") ||
strings.HasPrefix(value, "COVERAGE_DIFF_PROFILE=") ||
strings.HasPrefix(value, "COVERAGE_ARGS_LOG=") {
continue
}
baseEnv = append(baseEnv, value)
}
baseEnv = append(baseEnv, "PATH="+binDir+":"+os.Getenv("PATH"))
runGate := func(t *testing.T, diffProfile *string) []string {
t.Helper()
argsLog := filepath.Join(t.TempDir(), "args.log")
cmd := exec.Command(
"sh",
"./scripts/policy/check-coverage-gate.sh",
"--base-ref",
"HEAD",
)
cmd.Dir = root
cmd.Env = append(append([]string{}, baseEnv...), "COVERAGE_ARGS_LOG="+argsLog)
if diffProfile != nil {
cmd.Env = append(cmd.Env, "COVERAGE_DIFF_PROFILE="+*diffProfile)
}
output, runErr := cmd.CombinedOutput()
if runErr != nil {
t.Fatalf("coverage gate error = %v\noutput:\n%s", runErr, output)
}
data, readErr := os.ReadFile(argsLog)
if readErr != nil {
t.Fatalf("ReadFile(args log) error = %v", readErr)
}
return strings.Fields(string(data))
}
assertDiffProfiles := func(t *testing.T, args []string, want ...string) {
t.Helper()
var got []string
for i := 0; i+1 < len(args); i++ {
if args[i] == "--diff-profile" {
got = append(got, args[i+1])
i++
}
}
if strings.Join(got, "\n") != strings.Join(want, "\n") {
t.Fatalf("diff profiles = %q, want %q; args = %q", got, want, args)
}
}
t.Run("unset keeps strict policy profile", func(t *testing.T) {
assertDiffProfiles(
t,
runGate(t, nil),
"coverage-policy.txt",
"coverage.txt",
)
})
t.Run("explicit empty omits only policy profile", func(t *testing.T) {
empty := ""
assertDiffProfiles(t, runGate(t, &empty), "coverage.txt")
})
}