Skip to content
Merged
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
73 changes: 73 additions & 0 deletions .github/scripts/apply-code-quality-ruleset.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# apply-code-quality-ruleset.sh — Idempotently create/update the code-quality ruleset
#
# This script creates (or updates) the `code-quality` repository ruleset that
# enforces required status checks on the default branch of petry-projects/markets.
#
# Required status checks configured (derived from actual CI check run names):
# - SonarCloud sonarcloud.yml, job: sonarcloud (name: SonarCloud)
# - Analyze (actions) codeql.yml, job: analyze (name: Analyze), language: actions
# - claude-code / claude claude.yml, calling job: claude-code → reusable job: claude
#
# Standard reference:
# https://github.com/petry-projects/.github/blob/main/standards/github-settings.md#code-quality--required-checks-ruleset-all-repositories
#
# Usage:
# GH_TOKEN=<admin-token> bash .github/scripts/apply-code-quality-ruleset.sh
#
# The org-level script (petry-projects/.github/scripts/apply-rulesets.sh) is the
# canonical tool for managing rulesets across all repos. This script exists as a
# repo-local reference and fallback for the markets repository specifically.

set -euo pipefail

REPO="petry-projects/markets"
RULESET_NAME="code-quality"

if [ -z "${GH_TOKEN:-}" ]; then
echo "ERROR: GH_TOKEN is required with administration:write scope" >&2
exit 1
fi

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider validating required CLI dependencies up front (e.g., gh and jq) and emitting a clear error if missing. Right now the script will fail later with less actionable messages like command not found, which makes recovery usage harder.

Suggested change
MISSING_DEPENDENCY=0
for cmd in gh jq; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "ERROR: Required CLI dependency '$cmd' is not installed or not on PATH" >&2
MISSING_DEPENDENCY=1
fi
done
if [ "$MISSING_DEPENDENCY" -ne 0 ]; then
exit 1
fi

Copilot uses AI. Check for mistakes.
export GH_TOKEN

# Fetch existing rulesets
EXISTING_ID=$(gh api "repos/$REPO/rulesets" \
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id" 2>/dev/null || true)
Comment on lines +34 to +36

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gh api repos/$REPO/rulesets errors are currently suppressed (2>/dev/null || true). This can mask real failures (bad auth, missing permissions, API changes) and cause the script to behave as if no ruleset exists. Prefer surfacing errors, or explicitly handle only the expected “not found/empty list” cases.

Suggested change
# Fetch existing rulesets
EXISTING_ID=$(gh api "repos/$REPO/rulesets" \
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id" 2>/dev/null || true)
# Fetch existing rulesets. If no ruleset matches, --jq returns no output and
# EXISTING_ID remains empty; unexpected gh/api failures should surface.
EXISTING_ID=$(gh api "repos/$REPO/rulesets" \
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id")

Copilot uses AI. Check for mistakes.

Comment on lines +35 to +37

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EXISTING_ID can contain multiple IDs if more than one ruleset shares the same name (the jq filter can emit multiple lines). That would make the subsequent PUT URL invalid. Consider selecting a single ID deterministically (e.g., first match) and/or failing if multiple matches are found.

Suggested change
EXISTING_ID=$(gh api "repos/$REPO/rulesets" \
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id" 2>/dev/null || true)
mapfile -t EXISTING_IDS < <(
gh api "repos/$REPO/rulesets" \
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id" 2>/dev/null || true
)
if [ "${#EXISTING_IDS[@]}" -gt 1 ]; then
echo "ERROR: Multiple rulesets named $RULESET_NAME found for $REPO: ${EXISTING_IDS[*]}" >&2
exit 1
fi
EXISTING_ID="${EXISTING_IDS[0]:-}"

Copilot uses AI. Check for mistakes.
PAYLOAD=$(jq -n '{
name: "code-quality",
Comment on lines +38 to +39

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ruleset name is defined in RULESET_NAME but the payload hardcodes name: "code-quality". This duplication can lead to drift if the variable is ever updated. Prefer building the payload from RULESET_NAME to keep the script truly idempotent/maintainable.

Suggested change
PAYLOAD=$(jq -n '{
name: "code-quality",
PAYLOAD=$(jq -n --arg ruleset_name "$RULESET_NAME" '{
name: $ruleset_name,

Copilot uses AI. Check for mistakes.
target: "branch",
enforcement: "active",
conditions: {
ref_name: {
include: ["~DEFAULT_BRANCH"],
exclude: []
}
},
rules: [
{
type: "required_status_checks",
parameters: {
strict_required_status_checks_policy: true,
required_status_checks: [
{context: "SonarCloud"},
{context: "Analyze (actions)"},
{context: "claude-code / claude"}
]
}
}
],
bypass_actors: []
}')

if [ -n "$EXISTING_ID" ]; then
echo "Updating existing $RULESET_NAME ruleset (id=$EXISTING_ID) ..."
echo "$PAYLOAD" | gh api -X PUT "repos/$REPO/rulesets/$EXISTING_ID" --input - > /dev/null
echo "Done — ruleset updated: https://github.com/$REPO/rules/$EXISTING_ID"
else
echo "Creating $RULESET_NAME ruleset ..."
RESULT=$(echo "$PAYLOAD" | gh api -X POST "repos/$REPO/rulesets" --input -)
NEW_ID=$(echo "$RESULT" | jq -r '.id')
echo "Done — ruleset created: https://github.com/$REPO/rules/$NEW_ID"
fi
Loading