Skip to content

Merge pull request #5 from amirabbas-gh/changeset-release/version-pac… #10

Merge pull request #5 from amirabbas-gh/changeset-release/version-pac…

Merge pull request #5 from amirabbas-gh/changeset-release/version-pac… #10

Workflow file for this run

name: CI
on:
pull_request:
branches:
- main
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
pull-request:
name: Pull request checks
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: pnpm/action-setup@d15e628ca66d93ee5f352c71671a7bc6a97af5c9 # v6.0.8
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Get changed files
id: changed
run: |
files=$(git diff --name-only --diff-filter=ACMR origin/main...HEAD | tr '\n' ' ')
echo "files=$files" >> "$GITHUB_OUTPUT"
# Biome only formats/lints JS/TS/JSON — skip .md, .yaml, .sh, etc.
biome_files=""
for f in $(git diff --name-only --diff-filter=ACMR origin/main...HEAD); do
case "$f" in
*.ts|*.tsx|*.js|*.jsx|*.json|*.jsonc) biome_files="${biome_files} ${f}" ;;
esac
done
biome_files=$(echo "$biome_files" | xargs)
echo "biome_files=$biome_files" >> "$GITHUB_OUTPUT"
- name: Get changed codemod package dirs
id: codemods
run: |
roots=""
for f in $(git diff --name-only origin/main...HEAD -- 'codemods/' || true); do
[ -z "$f" ] && continue
d=$(dirname "$f")
while [ "$d" != "." ] && [ "$d" != "/" ]; do
if [ -f "$d/package.json" ] && [[ "$d" == codemods/* ]]; then
roots="${roots}"$'\n'"$d"
break
fi
parent=$(dirname "$d")
[ "$parent" = "$d" ] && break
d=$parent
done
done
dirs=$(printf '%s\n' "$roots" | sort -u | grep -v '^$' | tr '\n' ' ')
echo "dirs=$dirs" >> "$GITHUB_OUTPUT"
- name: Format check (changed files)
if: steps.changed.outputs.biome_files != ''
run: pnpm exec biome format ${{ steps.changed.outputs.biome_files }}
- name: Lint (changed files)
if: steps.changed.outputs.biome_files != ''
run: pnpm exec biome lint ${{ steps.changed.outputs.biome_files }}
- name: Markdown link check
run: pnpm run docs:links
- name: Test (changed codemods)
if: steps.codemods.outputs.dirs != ''
run: |
for dir in ${{ steps.codemods.outputs.dirs }}; do
(cd "$dir" && pnpm test)
done
- name: Typecheck (changed codemods)
if: steps.codemods.outputs.dirs != ''
run: |
for dir in ${{ steps.codemods.outputs.dirs }}; do
(cd "$dir" && pnpm run check-types)
done
push-verify:
name: Full workspace (main)
if: github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: pnpm/action-setup@d15e628ca66d93ee5f352c71671a7bc6a97af5c9 # v6.0.8
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run docs:links
- run: pnpm run ci
changeset-check:
name: Changeset Check
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: pnpm/action-setup@d15e628ca66d93ee5f352c71671a7bc6a97af5c9 # v6.0.8
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Check for changeset
env:
SKIP_LABEL: skip-changeset
PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
changed_dirs=""
for f in $(git diff --name-only --diff-filter=ACMR origin/main...HEAD -- 'codemods/' | grep -v '/tests/' || true); do
[ -z "$f" ] && continue
d=$(dirname "$f")
while [ "$d" != "." ] && [ "$d" != "/" ]; do
if [ -f "$d/package.json" ] && [[ "$d" == codemods/* ]]; then
changed_dirs="${changed_dirs}"$'\n'"$d"
break
fi
parent=$(dirname "$d")
[ "$parent" = "$d" ] && break
d=$parent
done
done
changed_dirs=$(printf '%s\n' "$changed_dirs" | sort -u | grep -v '^$' || true)
if [ -z "$changed_dirs" ]; then
echo "No codemod source files changed. Changeset not required."
exit 0
fi
changed_packages=""
for dir in $changed_dirs; do
if [ -f "$dir/package.json" ]; then
pkg=$(node -p "require('./$dir/package.json').name")
changed_packages="$changed_packages $pkg"
fi
done
changed_packages=$(echo "$changed_packages" | xargs)
if [ -z "$changed_packages" ]; then
echo "Changed directories have no package.json. Changeset not required."
exit 0
fi
echo "Changed packages:"
echo "$changed_packages" | tr ' ' '\n'
if echo "$PR_LABELS" | grep -q "$SKIP_LABEL"; then
echo "skip-changeset label found. Skipping changeset requirement."
exit 0
fi
changeset_files=$(git diff --name-only --diff-filter=ACMR origin/main...HEAD -- .changeset \
| grep '\.md$' \
| grep -v 'README.md' \
|| true)
covered_packages=""
has_empty_changeset=false
for f in $changeset_files; do
pkgs=$(sed -n '/^---$/,/^---$/{ /^---$/d; s/['\''`]//g; s/:.*//; p; }' "$f")
pkgs=$(echo "$pkgs" | xargs)
if [ -z "$pkgs" ]; then
has_empty_changeset=true
else
covered_packages="$covered_packages $pkgs"
fi
done
covered_packages=$(echo "$covered_packages" | xargs)
# Empty changeset: package.json-only edits do not need a named bump.
if [ "$has_empty_changeset" = true ]; then
filtered=""
for dir in $changed_dirs; do
[ -f "$dir/package.json" ] || continue
pkg=$(node -p "require('./$dir/package.json').name")
other=$(git diff --name-only origin/main...HEAD -- "$dir/" | grep -v 'package.json$' || true)
if [ -n "$other" ]; then
filtered="$filtered $pkg"
else
echo "Empty changeset waives changeset for $pkg (package.json only)."
fi
done
changed_packages=$(echo "$filtered" | xargs)
fi
missing=""
for pkg in $changed_packages; do
if ! printf '%s\n' $covered_packages | grep -Fxq "$pkg"; then
missing="$missing $pkg"
fi
done
missing=$(echo "$missing" | xargs)
if [ -z "$missing" ]; then
echo "All changed packages have changesets."
exit 0
fi
echo "::error::Missing changeset for: $missing"
echo ""
echo "The following packages were changed but not covered by a changeset:"
for pkg in $missing; do
echo " - $pkg"
done
echo ""
echo "You have three options:"
echo " 1. Run 'pnpm changeset' to add a changeset covering the missing packages"
echo " 2. Add an empty changeset (no packages selected) if no version bump is needed"
echo " 3. Add the 'skip-changeset' label to this PR"
exit 1