Skip to content

feat(core): add ProjectRef type to RunInput #136

feat(core): add ProjectRef type to RunInput

feat(core): add ProjectRef type to RunInput #136

Workflow file for this run

name: PR Validation
on:
pull_request:
branches: [master]
types: [opened, synchronize, reopened]
concurrency:
group: pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
env:
NODE_VERSION: '22'
jobs:
validate:
name: Validate Pull Request
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: 💬 Comment in progress
uses: actions/github-script@v8
with:
script: |
const marker = '<!-- pr-validation-bot -->';
const body = `${marker}
⏳ **PR Validation IN PROGRESS**
**Commit:** \`${{ github.event.pull_request.head.sha }}\`
**Branch:** \`${{ github.head_ref }}\`
**Checks:**
- ⏳ Release guard (no version/changelog changes)
- ⏳ Dependencies installed
- ⏳ Type check passed
- ⏳ Linting passed
- ⏳ Format check passed
- ⏳ Tests + coverage passed
- ⏳ Build successful
---
🔗 [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
⏰ Started at: \`${new Date().toISOString()}\``;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c =>
c.user.login === 'github-actions[bot]' && c.body.startsWith(marker)
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body: body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body,
});
}
- name: 📥 Checkout code
uses: actions/checkout@v6
- name: 🔧 Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: 📦 Install dependencies
id: install
run: npm ci
- name: 🔒 Release guard
id: release-guard
run: |
# Skip check for release/* branches — those are created by release-prepare
if [[ "${{ github.head_ref }}" == release/* ]]; then
echo "outcome=success" >> $GITHUB_OUTPUT
echo "✅ Release branch — version/changelog changes allowed"
exit 0
fi
ERRORS=""
# Check if any package.json version was changed
for pkg in packages/core packages/platform; do
VERSION_DIFF=$(git diff origin/${{ github.base_ref }}...HEAD -- ${pkg}/package.json | grep -E '^\+.*"version"' || true)
if [ -n "$VERSION_DIFF" ]; then
PKG_NAME=$(basename $pkg)
ERRORS="${ERRORS}\n- ❌ \`${pkg}/package.json\` version was modified — use \`release-prepare\` workflow instead"
fi
done
# Check if CHANGELOG.md was changed
CHANGELOG_DIFF=$(git diff origin/${{ github.base_ref }}...HEAD --name-only | grep -E '^CHANGELOG\.md$' || true)
if [ -n "$CHANGELOG_DIFF" ]; then
ERRORS="${ERRORS}\n- ❌ \`CHANGELOG.md\` was modified — changelog is auto-generated by \`release-prepare\` workflow"
fi
if [ -n "$ERRORS" ]; then
echo "outcome=failure" >> $GITHUB_OUTPUT
echo -e "⛔ Release guard failed:${ERRORS}"
echo -e "message=${ERRORS}" >> $GITHUB_OUTPUT
exit 1
else
echo "outcome=success" >> $GITHUB_OUTPUT
echo "✅ No version or changelog changes detected"
fi
- name: 🔍 Type check
id: type-check
if: always() && steps.install.outcome == 'success'
run: npm run type-check
- name: 🎨 Lint
id: lint
if: always() && steps.install.outcome == 'success'
run: npm run lint
- name: 🎨 Format check
id: format
if: always() && steps.install.outcome == 'success'
run: npm run format:check
- name: 🧪 Tests + coverage
id: test
if: always() && steps.install.outcome == 'success'
run: npm run test:coverage
- name: 🏗️ Build
id: build
if: always() && steps.install.outcome == 'success'
run: npm run build
- name: 💬 Comment on PR
if: always()
uses: actions/github-script@v8
with:
script: |
const marker = '<!-- pr-validation-bot -->';
const checks = [
{ name: 'Release guard (no version/changelog changes)', outcome: '${{ steps.release-guard.outcome }}' },
{ name: 'Dependencies installed', outcome: '${{ steps.install.outcome }}' },
{ name: 'Type check passed', outcome: '${{ steps.type-check.outcome }}' },
{ name: 'Linting passed', outcome: '${{ steps.lint.outcome }}' },
{ name: 'Format check passed', outcome: '${{ steps.format.outcome }}' },
{ name: 'Tests + coverage passed', outcome: '${{ steps.test.outcome }}' },
{ name: 'Build successful', outcome: '${{ steps.build.outcome }}' },
];
const allPassed = checks.every(c => c.outcome === 'success');
const status = allPassed ? '✅ PASSED' : '❌ FAILED';
const emoji = allPassed ? '🎉' : '💥';
const checkLines = checks
.map(c => `- ${c.outcome === 'success' ? '✅' : c.outcome === 'skipped' ? '⏭️' : '❌'} ${c.name}`)
.join('\n');
const body = `${marker}
${emoji} **PR Validation ${status}**
**Commit:** \`${{ github.event.pull_request.head.sha }}\`
**Branch:** \`${{ github.head_ref }}\`
**Checks:**
${checkLines}
${allPassed ? '**Ready to merge!** ✨' : '**Please fix the failing checks.**'}
---
🔗 [View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
⏰ Generated at: \`${new Date().toISOString()}\``;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c =>
c.user.login === 'github-actions[bot]' && c.body.startsWith(marker)
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body: body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body,
});
}