Skip to content

Create Temp Badges For Readme #211

Create Temp Badges For Readme

Create Temp Badges For Readme #211

---
name: Create Temp Badges For Readme
on:
schedule:
- cron: "45 4 * * *" # daily @ 04:45 UTC
workflow_dispatch: # manual runs via Actions UI
permissions:
contents: write
jobs:
Create-Badges:
runs-on: ubuntu-latest
env:
ORG: ansible-lockdown
TARGET_BRANCH: self_hosted
BADGES_DIR: badges
steps:
- name: Checkout target (badges) repo/branch
uses: actions/checkout@v4
with:
ref: ${{ env.TARGET_BRANCH }}
- name: Install tools
run: |
sudo apt-get update -y
sudo apt-get install -y jq
gh --version || true
- name: Discover CIS/STIG repos from GitHub API (exclude audits; build pairs)
id: discover
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
echo "🔎 Fetching org repos for '${ORG}'..."
gh api --paginate -H "Accept: application/vnd.github+json" "/orgs/${ORG}/repos?per_page=100&type=all" \
| jq -r '.[].name' \
| sort -u > all.txt
echo "Excluding audits and this repo..."
grep -Ev '(-Audit$|^github_windows_IaC$)' all.txt > base.txt || true
echo "Keeping names that end with -CIS or -STIG..."
awk '/^[A-Za-z0-9._-]+-(CIS|STIG)$/' base.txt > cisstig.txt
echo "Building CIS/STIG pairs and Private counterparts..."
: > targets.txt
while IFS= read -r name; do
base="${name%-CIS}"
if [ "$base" = "$name" ]; then base="${name%-STIG}"; fi
echo "${base}-CIS" >> targets.txt
echo "${base}-STIG" >> targets.txt
echo "Private-${base}-CIS" >> targets.txt
echo "Private-${base}-STIG" >> targets.txt
done < cisstig.txt
sort -u targets.txt > targets_unique.txt
echo "Final targets:"
nl -ba targets_unique.txt || true
echo "TARGET_LIST=$(tr '\n' ' ' < targets_unique.txt)" >> "$GITHUB_OUTPUT"
- name: Configure git (author)
run: |
git config user.name "actions-user"
git config user.email "actions@users.noreply.github.com"
- name: Generate placeholders (safe, clean, no overwrite of real badges)
env:
TARGET_LIST: ${{ steps.discover.outputs.TARGET_LIST }}
ORG: ${{ env.ORG }}
BADGES_DIR: ${{ env.BADGES_DIR }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
changed=0
created=0
cleaned=0
releases_with_tag=0
releases_no_release=0
mk_placeholder() { # $1 = label
jq -n --arg lbl "$1" \
'{schemaVersion:1,label:$lbl,message:"Not Available",color:"lightgrey"}'
}
is_placeholder_file() { # $1=path ; returns 0 if placeholder
jq -e '.message == "Not Available" or .message == "No Release"' "$1" >/dev/null 2>&1
}
create_if_missing_or_placeholder() { # $1=path $2=json
if [[ -f "$1" ]]; then
if is_placeholder_file "$1"; then
echo "Placeholder present (ok): $1"
else
echo "Real badge detected; SKIP: $1"
fi
else
echo "Seeding placeholder: $1"
mkdir -p "$(dirname "$1")"
printf '%s\n' "$2" > "$1"
git add "$1"
changed=1
created=$((created+1))
fi
}
write_release_badge_safely() { # $1=repo
local repo="$1"
local out="${BADGES_DIR}/${repo}/lockdown-release.json"
# If real badge exists (not placeholder), skip
if [[ -f "$out" ]] && ! is_placeholder_file "$out"; then
echo "Real Lockdown Release badge present; SKIP: $out"
return 0
fi
# Else refresh based on GitHub API
if rel=$(gh api -H "Accept: application/vnd.github+json" "/repos/${ORG}/${repo}/releases/latest" 2>/dev/null); then
tag=$(echo "$rel" | jq -r '.tag_name // .name // empty')
[[ -z "$tag" ]] && tag="unknown"
jq -n --arg msg "$tag" \
'{schemaVersion:1,label:"Lockdown Release",message:$msg,color:"blue"}' > "$out"
echo "${repo}: release -> $tag"
releases_with_tag=$((releases_with_tag+1))
else
jq -n \
'{schemaVersion:1,label:"Lockdown Release",message:"No Release",color:"lightgrey"}' > "$out"
echo "${repo}: no release -> wrote placeholder"
releases_no_release=$((releases_no_release+1))
fi
git add "$out"
changed=1
}
echo "🔧 Processing targets..."
for name in $TARGET_LIST; do
[[ -z "$name" ]] && continue
if [[ "$name" =~ -Audit$ ]]; then
echo "⏭Skip audit: $name"
continue
fi
# Cleanup: remove old files with wrong schema/extra keys
for f in "${BADGES_DIR}/${name}/"*.json; do
if [[ -f "$f" ]]; then
if ! jq -e 'has("schemaVersion") and has("label") and has("message") and has("color") and (keys|length==4)' "$f" >/dev/null 2>&1; then
echo "🧹 Cleaning old file with invalid schema: $f"
rm -f "$f"
git rm -f "$f" || true
cleaned=$((cleaned+1))
changed=1
fi
fi
done
if [[ "$name" == Private-* ]]; then
# Private repos: one file benchmark-version.json
json_priv=$(mk_placeholder "Benchmark Version")
create_if_missing_or_placeholder "${BADGES_DIR}/${name}/benchmark-version.json" "$json_priv"
else
# Public repos: main + devel + lockdown release
json_main=$(mk_placeholder "Benchmark Version (main)")
json_dev=$(mk_placeholder "Benchmark Version (devel)")
create_if_missing_or_placeholder "${BADGES_DIR}/${name}/benchmark-version-main.json" "$json_main"
create_if_missing_or_placeholder "${BADGES_DIR}/${name}/benchmark-version-devel.json" "$json_dev"
write_release_badge_safely "$name"
fi
done
echo "Summary:"
echo " New placeholders created: $created"
echo " Old invalid files cleaned: $cleaned"
echo " Release badges: with tag $releases_with_tag"
echo " Release badges: no release $releases_no_release"
if [ "$cleaned" -gt 0 ]; then
echo "NOTE: $cleaned invalid badge files were removed."
echo " → Fresh placeholders will be recreated automatically in the next run."
fi
echo "CHANGED=$changed" >> $GITHUB_ENV
- name: Pull latest changes (fast-forward only)
if: env.CHANGED == '1'
run: |
git fetch origin $TARGET_BRANCH
git pull --ff-only origin $TARGET_BRANCH || {
echo "Remote advanced; skipping push."
echo "CHANGED=0" >> $GITHUB_ENV
}
- name: Commit & push changes
if: env.CHANGED == '1'
run: |
git commit -m "badges: create/update placeholders and cleanup invalid" || true
git push origin $TARGET_BRANCH