diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..951c9cd --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,25 @@ +name: Validate governance sources + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +jobs: + validate: + name: Validate scripts and manifest + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Validate Python and shell sources + run: | + python3 -m py_compile scripts/repository_manifest.py scripts/validate-labels.py + scripts/repository_manifest.py repositories.txt + bash -n scripts/sync-labels.sh scripts/sync-templates.sh + bash scripts/test-sync-labels.sh diff --git a/scripts/sync-labels.sh b/scripts/sync-labels.sh index 04d3e5a..64c87e5 100755 --- a/scripts/sync-labels.sh +++ b/scripts/sync-labels.sh @@ -62,6 +62,11 @@ parse_targets() { for repo in "${TARGETS[@]}"; do contains_repo "$repo" || die "repository is not in repositories.txt: $repo" done + declare -A seen_targets=() + for repo in "${TARGETS[@]}"; do + [[ -z "${seen_targets[$repo]+x}" ]] || die "repository may be synced only once: $repo" + seen_targets[$repo]=1 + done } validate_label_file() { @@ -79,8 +84,8 @@ apply_yaml() { case "$line" in "- name:"*) name="${line#- name:}" - name="${name#\"}"; name="${name%\"}" name="${name##+([[:space:]])}"; name="${name%%+([[:space:]])}" + name="${name#\"}"; name="${name%\"}" ;; " color:"*) color="${line# color: }" @@ -107,6 +112,7 @@ apply_yaml() { done < "$file" } +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then read_manifest parse_targets "$@" @@ -135,3 +141,4 @@ for repo in "${TARGETS[@]}"; do done echo "Done." +fi diff --git a/scripts/test-sync-labels.sh b/scripts/test-sync-labels.sh new file mode 100755 index 0000000..f2f326f --- /dev/null +++ b/scripts/test-sync-labels.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "$ROOT/scripts/sync-labels.sh" + +output="$(APPLY=false apply_yaml test-repo "$ROOT/scripts/tests/quoted-label.yml")" +[[ "$output" == *'priority:\ urgent'* ]] || { + echo "quoted label value was not parsed" >&2 + exit 1 +} +[[ "$output" != *'"priority:'* ]] || { + echo "quoted label value retained its opening quote" >&2 + exit 1 +} diff --git a/scripts/tests/quoted-label.yml b/scripts/tests/quoted-label.yml new file mode 100644 index 0000000..7470747 --- /dev/null +++ b/scripts/tests/quoted-label.yml @@ -0,0 +1,3 @@ +- name: "priority: urgent" + color: "0366d6" + description: An urgency marker