Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions scripts/tests/policy-gates-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,27 @@
git -C "$invalid" add .github/workflows/test.yml
(cd "$invalid" && expect_fail "$workflow_gate")

reusable_valid="$fixture/reusable-valid"
init_fixture "$reusable_valid"
mkdir -p "$reusable_valid/.github/workflows"
Comment thread
hyperpolymath marked this conversation as resolved.
printf '%s\n' 'name: reusable' 'on: push' 'jobs:' ' gate:' ' uses: owner/repo/.github/workflows/gate.yml@0123456789012345678901234567890123456789' > "$reusable_valid/.github/workflows/test.yml"
git -C "$reusable_valid" add .github/workflows/test.yml
(cd "$reusable_valid" && expect_pass "$workflow_gate")

reusable_timeout="$fixture/reusable-timeout"
init_fixture "$reusable_timeout"
mkdir -p "$reusable_timeout/.github/workflows"
printf '%s\n' 'name: reusable' 'on: push' 'jobs:' ' gate:' ' timeout-minutes: 10' ' uses: owner/repo/.github/workflows/gate.yml@0123456789012345678901234567890123456789' > "$reusable_timeout/.github/workflows/test.yml"
Comment thread
hyperpolymath marked this conversation as resolved.
git -C "$reusable_timeout" add .github/workflows/test.yml
(cd "$reusable_timeout" && expect_fail "$workflow_gate")

runner_timeout="$fixture/runner-timeout"
init_fixture "$runner_timeout"
mkdir -p "$runner_timeout/.github/workflows"
printf '%s\n' 'name: runner' 'on: push' 'jobs:' ' test:' ' runs-on: ubuntu-latest' ' timeout-minutes: 10' ' steps:' ' - run: true' > "$runner_timeout/.github/workflows/test.yml"

Check warning on line 118 in scripts/tests/policy-gates-test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of using the literal 'on: push' 5 times.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBNa23jrqHCjlC5LlVb&open=AaBNa23jrqHCjlC5LlVb&pullRequest=691
git -C "$runner_timeout" add .github/workflows/test.yml
(cd "$runner_timeout" && expect_pass "$workflow_gate")

control="$fixture/control"
init_fixture "$control"
mkdir -p "$control/.github/workflows"
Expand Down
20 changes: 20 additions & 0 deletions tools/policy/check-workflows-parse.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@
esac
}

# GitHub rejects a reusable-workflow call job before creating any jobs when it
# contains step-job-only keys such as timeout-minutes. The file remains valid
# YAML, so the parser gate alone cannot see this zero-check failure mode.
has_reusable_timeout() {

Check warning on line 44 in tools/policy/check-workflows-parse.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBNY-EL_KYjlrKbqvn8&open=AaBNY-EL_KYjlrKbqvn8&pullRequest=691
case "$parser" in

Check failure on line 45 in tools/policy/check-workflows-parse.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a default case (*) to handle unexpected values.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBNY-EL_KYjlrKbqvn9&open=AaBNY-EL_KYjlrKbqvn9&pullRequest=691
yq)
yq -e '[.jobs[] | select(has("uses") and has("timeout-minutes"))] | length > 0' "$1" >/dev/null 2>&1

Check warning on line 47 in tools/policy/check-workflows-parse.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBNY-EL_KYjlrKbqvn-&open=AaBNY-EL_KYjlrKbqvn-&pullRequest=691
;;
python)
python3 -c 'import sys,yaml; d=yaml.safe_load(open(sys.argv[1], encoding="utf-8")) or {}; sys.exit(not any(isinstance(j,dict) and "uses" in j and "timeout-minutes" in j for j in (d.get("jobs") or {}).values()))' "$1"

Check warning on line 50 in tools/policy/check-workflows-parse.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBNY-EL_KYjlrKbqvn_&open=AaBNY-EL_KYjlrKbqvn_&pullRequest=691
;;
ruby)
ruby -ryaml -e 'd=YAML.safe_load(File.read(ARGV[0]), aliases: true) || {}; jobs=d["jobs"] || {}; exit(jobs.values.any? { |j| j.is_a?(Hash) && j.key?("uses") && j.key?("timeout-minutes") } ? 0 : 1)' "$1"

Check warning on line 53 in tools/policy/check-workflows-parse.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AaBNY-EL_KYjlrKbqvoA&open=AaBNY-EL_KYjlrKbqvoA&pullRequest=691
;;
esac
}

has_forbidden_control() {
od -An -v -tu1 "$1" | awk '
{ for (i=1; i<=NF; i++) if (($i < 9) || ($i > 10 && $i < 13) || ($i > 13 && $i < 32)) found=1 }
Expand All @@ -54,6 +71,9 @@
if has_forbidden_control "$file"; then
echo ' contains a YAML-forbidden control character'
fi
elif has_reusable_timeout "$file"; then
status=1
printf '%s\n' "::error file=$file::a reusable-workflow call job cannot declare timeout-minutes; GitHub rejects it before creating any jobs"
fi
done

Expand Down
Loading