Skip to content

fix: upload reliability, admin features, and recipe details page #41

fix: upload reliability, admin features, and recipe details page

fix: upload reliability, admin features, and recipe details page #41

Workflow file for this run

name: PR Compliance Checks
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [main]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
conventional-commits:
name: Validate Conventional Commits (Warning Only)
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
continue-on-error: true
permissions:
pull-requests: write
issues: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate conventional commits
uses: wagoid/commitlint-github-action@v6
with:
configFile: .commitlintrc.warning.json
continue-on-error: true
- name: Add commit message guidance comment
if: failure()
uses: actions/github-script@v7
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Conventional Commit Format')
);
if (!botComment) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: [
"## ⚠️ Conventional Commit Format",
"",
"Your commit messages don't follow the conventional commit format, but **this won't block your PR from being merged**.",
"",
"### Expected Format:",
"```",
"<type>[optional scope]: <description>",
"",
"[optional body]",
"",
"[optional footer(s)]",
"```",
"",
"### Examples:",
"- `feat: add changelog generation support`",
"- `fix: resolve login redirect issue`",
"- `docs: update README with new instructions`",
"- `chore: update dependencies`",
"",
"### Valid Types:",
"`feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`",
"",
"This helps with:",
"- πŸ“ Automatic changelog generation",
"- πŸš€ Automated semantic versioning",
"- πŸ“Š Better project history tracking",
"",
"*This is a non-blocking warning - your PR can still be merged without fixing this.*"
].join('\n')
});
}
code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run TypeScript type checking
run: npm run build
- name: Debug environment
run: |
echo "Node version: $(node --version)"
echo "NPM version: $(npm --version)"
echo "Current directory: $(pwd)"
echo "Package.json type: $(node -p 'JSON.parse(require("fs").readFileSync("package.json", "utf8")).type')"
ls -la node_modules/@nivo/ || echo "@nivo not found"
ls -la node_modules/d3-interpolate/ || echo "d3-interpolate not found"
- name: Run tests
run: npm test -- --coverage --passWithNoTests --reporter=verbose
env:
VITE_OPENAI_API_KEY: test-key-for-ci
NODE_OPTIONS: "--unhandled-rejections=strict"
- name: Upload coverage reports
uses: codecov/codecov-action@v4
with:
file: ./coverage/lcov.info
fail_ci_if_error: false
security-audit:
name: Security Audit
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
permissions:
security-events: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Fix vulnerabilities
run: npm audit fix
- name: Run npm audit
run: npm audit --audit-level=moderate
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
bundle-size:
name: Bundle Size Impact
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Analyze bundle size
run: |
echo "## Bundle Size Analysis" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Get bundle sizes
if [ -d "dist" ]; then
echo "### JavaScript Bundles:" >> $GITHUB_STEP_SUMMARY
find dist -name "*.js" -not -name "*.map" -exec du -h {} \; | sort -hr | head -10 >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### CSS Bundles:" >> $GITHUB_STEP_SUMMARY
find dist -name "*.css" -exec du -h {} \; | sort -hr >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Total Size:" >> $GITHUB_STEP_SUMMARY
du -sh dist >> $GITHUB_STEP_SUMMARY
# Check if bundle sizes are reasonable (warn if JS > 2MB)
total_js_size=$(find dist -name "*.js" -not -name "*.map" -exec stat -c%s {} \; | awk '{sum+=$1} END {print sum}')
if [ "$total_js_size" -gt 2097152 ]; then
echo "⚠️ **Warning**: Total JavaScript bundle size is $(( total_js_size / 1024 / 1024 ))MB" >> $GITHUB_STEP_SUMMARY
else
echo "βœ… Bundle size looks good!" >> $GITHUB_STEP_SUMMARY
fi
else
echo "❌ No dist folder found" >> $GITHUB_STEP_SUMMARY
fi
file-validation:
name: Required Files Check
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check required files
run: |
required_files=(
"package.json"
"README.md"
"LICENSE"
".gitignore"
"tsconfig.json"
)
missing_files=()
for file in "${required_files[@]}"; do
if [[ ! -f "$file" ]]; then
missing_files+=("$file")
fi
done
if [[ ${#missing_files[@]} -gt 0 ]]; then
echo "❌ Missing required files:"
printf '%s\n' "${missing_files[@]}"
exit 1
else
echo "βœ… All required files present"
fi
pr-labels:
name: PR Label Management
runs-on: ubuntu-latest
if: ${{ !github.event.pull_request.draft }}
permissions:
pull-requests: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Auto-label PR based on changes
uses: actions/labeler@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/pr-labeler.yml
compliance-summary:
name: Compliance Summary
runs-on: ubuntu-latest
needs: [conventional-commits, code-quality, security-audit, bundle-size, file-validation, pr-labels]
if: always() && !github.event.pull_request.draft
steps:
- name: Check compliance status
run: |
echo "## πŸ” Compliance Check Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "${{ needs.conventional-commits.result }}" == "success" ]]; then
echo "βœ… Conventional Commits: PASSED" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.conventional-commits.result }}" == "failure" ]]; then
echo "⚠️ Conventional Commits: WARNING (non-blocking)" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Conventional Commits: SKIPPED" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.code-quality.result }}" == "success" ]]; then
echo "βœ… Code Quality: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Code Quality: FAILED" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.security-audit.result }}" == "success" ]]; then
echo "βœ… Security Audit: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Security Audit: FAILED" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.bundle-size.result }}" == "success" ]]; then
echo "βœ… Bundle Size: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Bundle Size: FAILED" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.file-validation.result }}" == "success" ]]; then
echo "βœ… File Validation: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ File Validation: FAILED" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "πŸ“Š **Overall Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY