Create Temp Badges For Readme #211
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| 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 |