Update .changeset/README.md #40
Workflow file for this run
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
| # ------------------------------------------------------------- | ||
| # 🧪 PR Snapshot Diff (PNG/YML) | ||
| # Compares the PR branch against origin/main for snapshot changes | ||
| # under __snapshots__/ (PNG + YML). Posts a PR comment summary and | ||
| # enforces that visual/config snapshot changes require >= MINOR bump. | ||
| # ------------------------------------------------------------- | ||
| name: 🧪 PR Snapshot Diff (PNG/YML) | ||
| on: | ||
| pull_request: | ||
| branches: ["main"] | ||
| # Run on new PRs, updates (pushes), and when PRs are reopened/un-drafted. | ||
| types: [opened, synchronize, reopened, ready_for_review] | ||
| permissions: | ||
| # Read repo content to compute diffs; write to PR to post/update a comment. | ||
| contents: read | ||
| pull-requests: write | ||
| concurrency: | ||
| # Ensure only one snapshot job per PR runs at a time; cancel older runs. | ||
| group: pr-snapshot-diff-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
| jobs: | ||
| snapshot-diff: | ||
| name: 🔎 Snapshot changes (png/yml) & bump guard | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - # Check out the PR *head* commit (not the merge ref), with full history. | ||
| - name: ⏬ Checkout PR head (not merge ref) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| ref: ${{ github.event.pull_request.head.sha }} | ||
| # Make sure origin/main exists locally to diff against; unshallow if needed. | ||
| - name: 🔁 Ensure base (origin/main) is present | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| if [ -f .git/shallow ]; then | ||
| git fetch --unshallow --no-tags --prune | ||
| fi | ||
| git fetch --no-tags --prune origin +refs/heads/main:refs/remotes/origin/main | ||
| git rev-parse remotes/origin/main >/dev/null | ||
| # Early scan of changed .changeset/*.md files for 'minor'/'major'. | ||
| - name: 🔎 Early bump plan (fallback-only for skip) | ||
| id: early_plan | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| HAS_MINOR=0 | ||
| HAS_MAJOR=0 | ||
| git diff --name-only origin/main...HEAD -- .changeset/*.md > .cs-files || true | ||
| if [ -s .cs-files ]; then | ||
| while read -r f; do | ||
| [ -z "${f:-}" ] && continue | ||
| grep -qE ':\s*minor\b' "$f" && HAS_MINOR=1 || true | ||
| grep -qE ':\s*major\b' "$f" && HAS_MAJOR=1 || true | ||
| done < .cs-files | ||
| fi | ||
| { | ||
| echo "HAS_MINOR=${HAS_MINOR}" | ||
| echo "HAS_MAJOR=${HAS_MAJOR}" | ||
| } >> "$GITHUB_ENV" | ||
| # Compute unified diff + name-status for PNG/YML snapshot files. | ||
| # Build a Markdown summary and export counters via $GITHUB_ENV. | ||
| - name: 🧾 Collect changed PNG/YML snapshots | ||
| id: diff | ||
| if: env.HAS_MINOR == '0' && env.HAS_MAJOR == '0' | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| git diff --unified=3 --no-color origin/main...HEAD -- __snapshots__/**/*.{png,yml} > snapshots.diff || true | ||
| git diff --name-status origin/main...HEAD -- __snapshots__/**/*.{png,yml} > snapshots.list || true | ||
| # Robust counters (tolerant if file is empty/missing) | ||
| TOTAL=$(wc -l < snapshots.list 2>/dev/null | tr -d '[:space:]' || echo 0) | ||
| ADDED=$(grep -E '^[A]\s' snapshots.list 2>/dev/null | wc -l | tr -d '[:space:]' || echo 0) | ||
| MOD=$(grep -E '^[M]\s' snapshots.list 2>/dev/null | wc -l | tr -d '[:space:]' || echo 0) | ||
| DEL=$(grep -E '^[D]\s' snapshots.list 2>/dev/null | wc -l | tr -d '[:space:]' || echo 0) | ||
| REN=$(grep -E '^[R]\d*\s' snapshots.list 2>/dev/null | wc -l | tr -d '[:space:]' || echo 0) | ||
| # Build a short table (first 200 rows) for the PR comment | ||
| head -n 200 snapshots.list > snapshots.short || true | ||
| { | ||
| echo "### Snapshot Changes (PNG/YML)" | ||
| echo | ||
| if [ "${TOTAL}" = "0" ]; then | ||
| echo "_No \`__snapshots__/**/*.{png,yml}\` changes detected._" | ||
| else | ||
| echo "- Total: **${TOTAL}** (added: ${ADDED}, modified: ${MOD}, deleted: ${DEL}, renamed: ${REN})" | ||
| echo | ||
| echo "| Status | File |" | ||
| echo "|-------:|:-----|" | ||
| while read -r LINE; do | ||
| [ -z "${LINE:-}" ] && continue | ||
| STATUS=$(echo "$LINE" | awk '{print $1}') | ||
| FILE=$(echo "$LINE" | awk '{print $2}') | ||
| if echo "$STATUS" | grep -qE '^R'; then | ||
| FILE=$(echo "$LINE" | awk '{print $3}') | ||
| fi | ||
| echo "| \`$STATUS\` | \`$FILE\` |" | ||
| done < snapshots.short | ||
| if [ "$TOTAL" -gt 200 ]; then | ||
| echo "" | ||
| echo "_…and $(($TOTAL - 200)) more_" | ||
| fi | ||
| fi | ||
| echo "" | ||
| echo "<!-- snapshot-summary-marker -->" | ||
| } > snapshot-summary.md | ||
| # Export counters and the summary path as job environment variables | ||
| { | ||
| echo "SNAP_TOTAL=${TOTAL}" | ||
| echo "SNAP_ADDED=${ADDED}" | ||
| echo "SNAP_MODIFIED=${MOD}" | ||
| echo "SNAP_DELETED=${DEL}" | ||
| echo "SNAP_RENAMED=${REN}" | ||
| echo "SNAP_SUMMARY_MD_PATH=$(pwd)/snapshot-summary.md" | ||
| } >> "$GITHUB_ENV" | ||
| # Attach the full unified diff as a downloadable artifact if there are changes. | ||
| - name: 📎 Upload unified diff (artifact) | ||
| if: env.HAS_MINOR == '0' && env.HAS_MAJOR == '0' && env.SNAP_TOTAL && env.SNAP_TOTAL != '0' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: snapshots-diff | ||
| path: snapshots.diff | ||
| if-no-files-found: ignore | ||
| retention-days: 7 | ||
| # Post (or update) a PR comment with the table summary. | ||
| - name: 💬 Upsert PR comment | ||
| if: env.HAS_MINOR == '0' && env.HAS_MAJOR == '0' | ||
| uses: actions/github-script@v7 | ||
| env: | ||
| SNAP_SUMMARY_MD_PATH: ${{ env.SNAP_SUMMARY_MD_PATH }} | ||
| with: | ||
| script: | | ||
| const fs = require('node:fs'); | ||
| const { owner, repo, number } = context.issue; | ||
| const marker = '<!-- snapshot-summary-marker -->'; | ||
| let body = '_No snapshot info._'; | ||
| try { | ||
| const p = process.env.SNAP_SUMMARY_MD_PATH; | ||
| if (p && fs.existsSync(p)) body = fs.readFileSync(p, 'utf8'); | ||
| } catch {} | ||
| const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: number, per_page: 100 }); | ||
| const existing = comments.find(c => c.user?.type === 'Bot' && c.body?.includes(marker)); | ||
| if (existing) { | ||
| await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }); | ||
| } else { | ||
| await github.rest.issues.createComment({ owner, repo, issue_number: number, body }); | ||
| } | ||
| # Set up Node + install deps so `npx changeset` can run reliably. | ||
| - name: 🟦 Setup Node (for changeset status) | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version-file: ".nvmrc" | ||
| cache: "npm" | ||
| - name: 📦 Install deps (root) | ||
| run: npm ci | ||
| # Determine if the PR’s changesets imply a MINOR/MAJOR bump. | ||
| # Primary source: changesets JSON; | ||
| - name: 🔎 Determine bump plan (JSON only) | ||
| id: plan | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| npx changeset status --since=origin/main --output=json > .changeset-status.json || true | ||
| # Parse JSON and emit HAS_MINOR/HAS_MAJOR to a temp env file | ||
| node > .changeset-env <<'NODE' | ||
| const fs = require('node:fs'); | ||
| let hasMinor = 0, hasMajor = 0; | ||
| try { | ||
| const txt = fs.readFileSync('.changeset-status.json','utf8').trim(); | ||
| if (txt) { | ||
| const j = JSON.parse(txt); | ||
| for (const r of (j.releases || [])) { | ||
| if (r.type === 'minor') hasMinor = 1; | ||
| if (r.type === 'major') hasMajor = 1; | ||
| } | ||
| } | ||
| } catch (_) {} | ||
| process.stdout.write(`HAS_MINOR=${hasMinor}\nHAS_MAJOR=${hasMajor}\n`); | ||
| NODE | ||
| cat .changeset-env >> "$GITHUB_ENV" | ||
| # Guardrail: if snapshots changed, require at least MINOR (or MAJOR). | ||
| # This prevents accidental PATCH releases for visual/markup-impacting changes. | ||
| - name: 🚦 Enforce Snapshot changes require >= minor | ||
| if: env.HAS_MINOR == '0' && env.HAS_MAJOR == '0' && env.SNAP_TOTAL && env.SNAP_TOTAL != '0' | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| if [ "${HAS_MINOR}" = "0" ] && [ "${HAS_MAJOR}" = "0" ]; then | ||
| echo "::error title=Snapshots changed but only patch detected::PNG/YML snapshots changed. Please bump at least MINOR in your changeset." | ||
| exit 1 | ||
| else | ||
| echo "Snapshot changes and non-patch bump present → OK." | ||
| fi | ||