Skip to content

feat: add validate-codemod-recipe agent skill #204

feat: add validate-codemod-recipe agent skill

feat: add validate-codemod-recipe agent skill #204

Workflow file for this run

name: CI
on:
pull_request:
branches:
- main
concurrency:
group: ci-${{ github.head_ref }}
cancel-in-progress: true
jobs:
test:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- name: Enable Corepack
run: corepack enable
- name: Get Yarn cache path
id: yarn-cache
run: echo "dir=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: yarn-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
yarn-${{ runner.os }}-
- run: yarn install --immutable
- 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"
lint_files=$(git diff --name-only --diff-filter=ACMR origin/main...HEAD \
| grep -E '\.(ts|js|mts|mjs|tsx|jsx)$' | tr '\n' ' ')
echo "lint_files=$lint_files" >> "$GITHUB_OUTPUT"
- name: Get changed codemods
id: codemods
run: |
dirs=$(git diff --name-only origin/main...HEAD -- 'codemods/' \
| awk -F/ 'NF>=3 {print $1"/"$2"/"$3}' | sort -u | tr '\n' ' ')
echo "dirs=$dirs" >> "$GITHUB_OUTPUT"
- name: Format check (changed files)
if: steps.changed.outputs.files != ''
run: yarn format:check ${{ steps.changed.outputs.files }}
- name: Lint (changed files)
if: steps.changed.outputs.lint_files != ''
run: yarn lint ${{ steps.changed.outputs.lint_files }}
- name: Test (changed codemods)
if: steps.codemods.outputs.dirs != ''
run: |
for dir in ${{ steps.codemods.outputs.dirs }}; do
(cd "$dir" && yarn test)
done
- name: README freshness check
if: steps.codemods.outputs.dirs != ''
run: |
yarn readme
if ! git diff --quiet README.md; then
echo "::error::README.md is out of date. Run 'yarn readme' and commit the result."
git diff README.md
exit 1
fi
changeset-check:
name: Changeset Check
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
- name: Check for changeset
env:
SKIP_LABEL: skip-changeset
PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
# Find changed codemod package directories (excluding tests)
changed_dirs=$(git diff --name-only --diff-filter=ACMR origin/main...HEAD -- 'codemods/' \
| grep -v '/tests/' \
| awk -F/ 'NF>=3 {print $1"/"$2"/"$3}' | sort -u)
if [ -z "$changed_dirs" ]; then
echo "No codemod source files changed. Changeset not required."
exit 0
fi
# Resolve changed directories to package names
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'
# Check for skip-changeset label
if echo "$PR_LABELS" | grep -q "$SKIP_LABEL"; then
echo "skip-changeset label found. Skipping changeset requirement."
exit 0
fi
# Collect package names mentioned in new changeset files
changeset_files=$(git diff --name-only --diff-filter=ACMR origin/main...HEAD -- '.changeset/*.md' \
| grep -v 'README.md' \
|| true)
covered_packages=""
for f in $changeset_files; do
# Extract package names from YAML frontmatter (between --- delimiters)
pkgs=$(sed -n '/^---$/,/^---$/{ /^---$/d; s/['\''"]//g; s/:.*//; p; }' "$f")
covered_packages="$covered_packages $pkgs"
done
covered_packages=$(echo "$covered_packages" | xargs)
# Check each changed package is covered
missing=""
for pkg in $changed_packages; do
if ! echo "$covered_packages" | grep -qw "$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 'yarn 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