name: Sync Wiki on: push: branches: [main] paths: - 'wiki/**' workflow_dispatch: permissions: read-all concurrency: group: wiki-sync cancel-in-progress: false jobs: sync-wiki: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Sync wiki folder to repository wiki env: AUTOMATION_TOKEN: ${{ secrets.POLL_NVD_CVES_PAT }} run: | set -euo pipefail if [ ! -d wiki ]; then echo "::error::wiki/ directory not found" exit 1 fi if [ -z "$AUTOMATION_TOKEN" ]; then echo "::error::Set POLL_NVD_CVES_PAT with repo write permissions." exit 1 fi # GitHub Wiki root (/wiki) renders Home.md, not INDEX.md. # INDEX.md is the canonical source; generate Home.md from it. if [ ! -f wiki/INDEX.md ]; then echo "::error::wiki/INDEX.md not found. It is required to generate wiki/Home.md." exit 1 fi cp wiki/INDEX.md wiki/Home.md REPO_API_JSON="$(mktemp)" REPO_API_STATUS="$(curl -sS -o "$REPO_API_JSON" -w "%{http_code}" -H "Authorization: Bearer ${AUTOMATION_TOKEN}" -H "Accept: application/vnd.github+json" "https://api.github.com/repos/${{ github.repository }}")" if [ "$REPO_API_STATUS" = "401" ]; then echo "::error::POLL_NVD_CVES_PAT is invalid/expired, or not SSO-authorized for this org." exit 1 fi if [ "$REPO_API_STATUS" = "404" ]; then echo "::error::POLL_NVD_CVES_PAT cannot access ${{ github.repository }}." exit 1 fi if [ "$REPO_API_STATUS" != "200" ]; then REPO_API_MESSAGE="$(jq -r '.message // empty' "$REPO_API_JSON" || true)" echo "::error::Unexpected GitHub API response (${REPO_API_STATUS}) while validating token. ${REPO_API_MESSAGE}" exit 1 fi REPO_PUSH_PERMISSION="$(jq -r '.permissions.push // false' "$REPO_API_JSON" || true)" if [ "$REPO_PUSH_PERMISSION" != "true" ]; then echo "::error::POLL_NVD_CVES_PAT cannot push to ${{ github.repository }}. Grant Contents: write (fine-grained PAT) or repo scope (classic PAT), and ensure org approval/SSO authorization if required." exit 1 fi WIKI_REMOTE="https://x-access-token:${AUTOMATION_TOKEN}@github.com/${{ github.repository }}.wiki.git" if ! git ls-remote "$WIKI_REMOTE" >/dev/null 2>&1; then echo "::warning::Wiki remote unavailable (repository wiki may be disabled). Skipping sync." exit 0 fi WIKI_TMP="$(mktemp -d)" trap 'rm -rf "$WIKI_TMP"' EXIT git clone --depth 1 "$WIKI_REMOTE" "$WIKI_TMP" rsync -a --delete --exclude '.git/' wiki/ "$WIKI_TMP/" cd "$WIKI_TMP" if [ -z "$(git status --porcelain)" ]; then echo "No wiki changes to sync." exit 0 fi WIKI_HEAD_REF="$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null || true)" if [ -n "$WIKI_HEAD_REF" ]; then WIKI_BRANCH="${WIKI_HEAD_REF#origin/}" else WIKI_BRANCH="master" fi git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add -A git commit -m "docs(wiki): sync from ${GITHUB_SHA}" # Clone may sanitize credentials from origin URL; push with explicit auth URL. git push "$WIKI_REMOTE" HEAD:"$WIKI_BRANCH"