diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..fa1c77a3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: 🐛 Bug Report +about: Report a bug or unexpected behavior +title: '[Bug]: ' +labels: ['bug', 'needs-triage'] +assignees: [] +--- + +## Bug Description + + +## Steps to Reproduce +1. +2. +3. + +## Expected Behavior + + +## Actual Behavior + + +## Environment +- **Object UI Version**: +- **React Version**: +- **Node Version**: +- **Browser**: +- **OS**: + +## Reproduction + + + +## Additional Context + + + +## Possible Solution + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..ff76123c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: 💬 Discord Community + url: https://discord.gg/objectstack + about: Join our Discord community for questions and discussions + - name: 📖 Documentation + url: https://www.objectui.org + about: Check our documentation for guides and API references + - name: 💡 Feature Request + url: https://github.com/objectstack-ai/objectui/discussions/categories/ideas + about: Share your ideas and feature requests in discussions diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..265afa9e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,32 @@ +--- +name: ✨ Feature Request +about: Suggest a new feature or enhancement +title: '[Feature]: ' +labels: ['enhancement', 'needs-triage'] +assignees: [] +--- + +## Feature Description + + +## Problem Statement + + + +## Proposed Solution + + +## Alternative Solutions + + +## Use Cases + + +## Additional Context + + +## Would you be willing to contribute? + +- [ ] Yes, I'm willing to contribute +- [ ] No, but I'd like to help test it +- [ ] No, but I'd love to see it implemented diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..071220df --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,70 @@ +## Description + + +## Type of Change + + +- [ ] 🐛 Bug fix (non-breaking change which fixes an issue) +- [ ] ✨ New feature (non-breaking change which adds functionality) +- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] 📝 Documentation update +- [ ] 🎨 Style/UI update (no functional changes) +- [ ] ♻️ Refactoring (no functional changes) +- [ ] ⚡ Performance improvement +- [ ] ✅ Test update +- [ ] 🔧 Build/configuration change +- [ ] 🔒 Security fix + +## Related Issues + + +Closes # +Related to # + +## Changes Made + + +- +- +- + +## Screenshots (if applicable) + + +## Testing + + +### Test Environment +- **Node Version**: +- **pnpm Version**: +- **OS**: + +### Test Steps +1. +2. +3. + +## Checklist + + +- [ ] My code follows the project's code style +- [ ] I have performed a self-review of my code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published + +## Breaking Changes + + +None + +## Migration Guide + + +N/A + +## Additional Notes + diff --git a/.github/WORKFLOWS.md b/.github/WORKFLOWS.md new file mode 100644 index 00000000..9ab65437 --- /dev/null +++ b/.github/WORKFLOWS.md @@ -0,0 +1,278 @@ +# GitHub Workflows Documentation + +This document describes the automated workflows configured for the Object UI repository. + +## Overview + +Our GitHub Actions workflows automate testing, security scanning, dependency management, and deployment processes. All workflows are located in `.github/workflows/`. + +## Workflows + +### 1. CI (Continuous Integration) + +**File**: `ci.yml` +**Triggers**: Push to `main`/`develop`, Pull Requests + +This is the main CI pipeline that ensures code quality. + +**Jobs**: +- **Test**: Runs tests on Node.js 18.x and 20.x + - Executes unit and integration tests + - Generates coverage reports (Node 20.x only) + - Uploads coverage to Codecov + +- **Lint**: Checks code style and quality + - Runs ESLint on all packages + - Ensures code follows project standards + +- **Build**: Validates that all packages build successfully + - Builds all packages in the monorepo + - Verifies build artifacts are created + +**Optimizations**: +- Uses pnpm store caching for faster dependency installation +- Runs jobs in parallel when possible +- Only uploads coverage on Node 20.x to save time + +### 2. CodeQL Security Scan + +**File**: `codeql.yml` +**Triggers**: Push to `main`/`develop`, Pull Requests, Weekly schedule (Mondays) + +Analyzes code for security vulnerabilities using GitHub's CodeQL engine. + +**Features**: +- Scans JavaScript/TypeScript code +- Uses security-extended and security-and-quality query packs +- Runs automatically on schedule to catch new vulnerabilities +- Results visible in Security tab + +### 3. PR Checks + +**File**: `pr-checks.yml` +**Triggers**: Pull Request opened/synchronized/reopened + +Validates pull requests and provides feedback. + +**Actions**: +- Runs type checking (via build) +- Executes tests +- Runs linter (continues on error) +- Posts success comment when all checks pass + +### 4. Auto Label PRs + +**File**: `labeler.yml` +**Configuration**: `labeler.yml` +**Triggers**: Pull Request opened/synchronized/reopened + +Automatically labels PRs based on changed files. + +**Labels Applied**: +- Package-specific labels (e.g., `package: core`, `package: react`) +- Plugin labels (e.g., `plugin: charts`) +- Category labels (e.g., `documentation`, `tests`, `configuration`) +- Scope labels (e.g., `examples`, `apps`, `ci/cd`) + +### 5. Bundle Size Check + +**File**: `size-check.yml` +**Triggers**: Pull Requests (when package files change) + +Reports bundle size changes in PR comments. + +**Features**: +- Calculates size of built packages +- Reports both raw and gzipped sizes +- Shows size warnings for large packages +- Posts results as PR comment + +**Size Limits**: +- Core packages: < 50KB gzipped +- Component packages: < 100KB gzipped +- Plugin packages: < 150KB gzipped + +### 6. Deploy Documentation + +**File**: `deploy-docs.yml` +**Triggers**: Push to `main` (docs changes), Manual workflow dispatch + +Builds and deploys documentation to GitHub Pages. + +**Steps**: +1. Builds VitePress documentation +2. Uploads artifact to GitHub Pages +3. Deploys to production + +**Access**: Documentation available at https://www.objectui.org + +### 7. Release + +**File**: `release.yml` +**Triggers**: Push of version tags (e.g., `v1.0.0`) + +Creates GitHub releases and publishes packages. + +**Process**: +1. Runs tests to ensure quality +2. Builds all packages +3. Creates GitHub release with changelog +4. (Optional) Publishes to npm registry + +**Note**: npm publishing is currently disabled. Uncomment the publish step when ready. + +### 8. Stale Issues & PRs + +**File**: `stale.yml` +**Triggers**: Daily schedule, Manual workflow dispatch + +Manages stale issues and pull requests. + +**Configuration**: +- Issues: Marked stale after 60 days, closed after 7 more days +- PRs: Marked stale after 45 days, closed after 14 more days +- Exempt labels: `pinned`, `security`, `critical`, `bug`, `enhancement` +- Can be reopened if activity resumes + +### 9. Dependabot Auto-merge + +**File**: `dependabot-auto-merge.yml` +**Configuration**: `dependabot.yml` +**Triggers**: Dependabot pull requests + +Automatically manages dependency updates. + +**Behavior**: +- **Patch/Minor updates**: Auto-approved and auto-merged +- **Major updates**: Commented for manual review +- Only merges after CI checks pass + +**Dependabot Configuration**: +- Weekly npm dependency updates (Mondays) +- Weekly GitHub Actions updates +- Groups related dependencies +- Limits to 10 open PRs + +### 10. Auto Changelog + +**File**: `changelog.yml` +**Triggers**: Release published, Manual workflow dispatch + +Generates and updates CHANGELOG.md from git history. + +**Note**: Requires `cliff.toml` configuration file for customization. + +## Security Features + +### CodeQL Analysis +- Continuous security monitoring +- Detects common vulnerabilities: + - SQL injection + - XSS vulnerabilities + - Path traversal + - Command injection + - Sensitive data exposure + +### Dependabot +- Automated dependency updates +- Security vulnerability alerts +- Grouped updates by category +- Auto-merge for safe updates + +### Permissions +All workflows follow the principle of least privilege: +- Read-only access by default +- Write permissions only when needed +- Explicit permission declarations + +## Issue & PR Templates + +### Issue Templates +- **Bug Report**: Structured bug reporting with environment details +- **Feature Request**: Feature proposals with use cases +- **Config**: Links to Discord, documentation, and discussions + +### Pull Request Template +- Comprehensive checklist +- Change type classification +- Testing requirements +- Breaking change documentation +- Migration guide section + +## Workflow Badges + +Add these badges to show workflow status: + +```markdown +[![CI](https://github.com/objectstack-ai/objectui/workflows/CI/badge.svg)](https://github.com/objectstack-ai/objectui/actions/workflows/ci.yml) +[![CodeQL](https://github.com/objectstack-ai/objectui/workflows/CodeQL%20Security%20Scan/badge.svg)](https://github.com/objectstack-ai/objectui/actions/workflows/codeql.yml) +``` + +## Best Practices + +### For Contributors +1. **Run checks locally first**: Use `pnpm lint`, `pnpm test`, `pnpm build` +2. **Keep PRs focused**: One feature or fix per PR +3. **Watch workflow results**: Fix failures promptly +4. **Update documentation**: For user-facing changes + +### For Maintainers +1. **Review auto-merge settings**: Verify Dependabot merges are safe +2. **Monitor security alerts**: Act on CodeQL findings +3. **Manage stale items**: Review before auto-closure +4. **Keep workflows updated**: Regular dependency updates for actions + +## Troubleshooting + +### Common Issues + +**Problem**: CI fails with "pnpm: command not found" +- **Solution**: Ensure `pnpm/action-setup@v4` is configured correctly + +**Problem**: Tests timeout +- **Solution**: Increase timeout in workflow or optimize tests + +**Problem**: Bundle size check fails +- **Solution**: Review size report, optimize imports, use code splitting + +**Problem**: CodeQL analysis fails +- **Solution**: Check for syntax errors, review CodeQL logs + +### Getting Help + +- Check [GitHub Actions documentation](https://docs.github.com/en/actions) +- Review workflow logs in Actions tab +- Ask in Discord community +- Create an issue for workflow problems + +## Maintenance + +### Regular Tasks +- [ ] Review and update GitHub Actions versions monthly +- [ ] Monitor CodeQL findings weekly +- [ ] Review Dependabot PRs weekly +- [ ] Update workflow documentation for changes +- [ ] Review stale item closure weekly + +### Updating Workflows +1. Test changes in a fork first +2. Use workflow dispatch for manual testing +3. Update documentation +4. Monitor first few runs after changes + +## Future Enhancements + +Potential workflow additions: +- [ ] Visual regression testing +- [ ] Performance benchmarking +- [ ] Automated canary releases +- [ ] Integration tests with examples +- [ ] Automated component documentation generation +- [ ] npm package publishing automation + +## Resources + +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Dependabot Documentation](https://docs.github.com/en/code-security/dependabot) +- [CodeQL Documentation](https://codeql.github.com/docs/) +- [Conventional Commits](https://www.conventionalcommits.org/) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..8de9759b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,59 @@ +version: 2 +updates: + # Enable version updates for npm + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "automated" + commit-message: + prefix: "chore" + include: "scope" + groups: + # Group all patch updates together + patch-updates: + patterns: + - "*" + update-types: + - "patch" + # Group dev dependencies + dev-dependencies: + dependency-type: "development" + update-types: + - "minor" + - "patch" + # Group React ecosystem updates + react: + patterns: + - "react*" + - "@types/react*" + update-types: + - "minor" + - "patch" + # Group testing libraries + testing: + patterns: + - "*testing*" + - "vitest*" + - "@vitest*" + update-types: + - "minor" + - "patch" + + # Enable version updates for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + labels: + - "dependencies" + - "github-actions" + - "automated" + commit-message: + prefix: "chore" + include: "scope" diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..2c1ccb9e --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,112 @@ +# Configuration for pull-requests labeler +# https://github.com/actions/labeler + +# Core packages +'package: core': + - changed-files: + - any-glob-to-any-file: 'packages/core/**/*' + +'package: types': + - changed-files: + - any-glob-to-any-file: 'packages/types/**/*' + +'package: react': + - changed-files: + - any-glob-to-any-file: 'packages/react/**/*' + +'package: components': + - changed-files: + - any-glob-to-any-file: 'packages/components/**/*' + +# Plugins +'plugin': + - changed-files: + - any-glob-to-any-file: 'packages/plugin-*/**/*' + +'plugin: charts': + - changed-files: + - any-glob-to-any-file: 'packages/plugin-charts/**/*' + +'plugin: editor': + - changed-files: + - any-glob-to-any-file: 'packages/plugin-editor/**/*' + +'plugin: kanban': + - changed-files: + - any-glob-to-any-file: 'packages/plugin-kanban/**/*' + +'plugin: markdown': + - changed-files: + - any-glob-to-any-file: 'packages/plugin-markdown/**/*' + +# Data adapters +'data-adapter': + - changed-files: + - any-glob-to-any-file: 'packages/data-*/**/*' + +# Designer +'designer': + - changed-files: + - any-glob-to-any-file: 'packages/designer/**/*' + +# Documentation +'documentation': + - changed-files: + - any-glob-to-any-file: + - 'docs/**/*' + - '*.md' + - 'packages/**/README.md' + +# Tests +'tests': + - changed-files: + - any-glob-to-any-file: + - '**/*.test.ts' + - '**/*.test.tsx' + - '**/*.spec.ts' + - '**/*.spec.tsx' + - '**/test/**/*' + - '**/tests/**/*' + - '**/__tests__/**/*' + +# Configuration +'configuration': + - changed-files: + - any-glob-to-any-file: + - '*.config.*' + - '.*rc' + - '.*rc.*' + - '.github/**/*' + - 'tsconfig*.json' + - 'package.json' + - 'pnpm-workspace.yaml' + +# Dependencies +'dependencies': + - changed-files: + - any-glob-to-any-file: + - 'package.json' + - 'pnpm-lock.yaml' + - '**/package.json' + +# Examples +'examples': + - changed-files: + - any-glob-to-any-file: 'examples/**/*' + +# Applications +'apps': + - changed-files: + - any-glob-to-any-file: 'apps/**/*' + +# CI/CD +'ci/cd': + - changed-files: + - any-glob-to-any-file: '.github/workflows/**/*' + +# Breaking changes (when certain files are modified) +'breaking-change': + - changed-files: + - any-glob-to-any-file: + - 'packages/types/src/schema/**/*' + - 'packages/core/src/public-api.ts' diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 00000000..110360cc --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,36 @@ +name: Auto Changelog + +on: + release: + types: [published] + workflow_dispatch: + +permissions: + contents: write + pull-requests: read + +jobs: + changelog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate changelog + uses: orhun/git-cliff-action@v4 + id: changelog + with: + config: cliff.toml + args: --verbose --latest + env: + OUTPUT: CHANGELOG.md + + - name: Commit changelog + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add CHANGELOG.md + git commit -m "docs: update CHANGELOG.md for ${{ github.event.release.tag_name }}" || echo "No changes to commit" + git push diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea5a26ac..cfb2e2db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,19 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'pnpm' + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install dependencies run: pnpm install --frozen-lockfile @@ -44,6 +57,7 @@ jobs: uses: codecov/codecov-action@v4 with: fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} lint: name: Lint @@ -64,6 +78,19 @@ jobs: node-version: '20.x' cache: 'pnpm' + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install dependencies run: pnpm install --frozen-lockfile @@ -89,6 +116,19 @@ jobs: node-version: '20.x' cache: 'pnpm' + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install dependencies run: pnpm install --frozen-lockfile diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..10cdaade --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,44 @@ +name: CodeQL Security Scan + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + schedule: + # Run at 00:00 UTC every Monday + - cron: '0 0 * * 1' + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + name: Analyze Code + runs-on: ubuntu-latest + timeout-minutes: 360 + + strategy: + fail-fast: false + matrix: + language: ['javascript-typescript'] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + queries: security-extended,security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 00000000..013d5fc5 --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,56 @@ +name: Dependabot Auto-merge + +on: + pull_request: + branches: [main, develop] + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' }} + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v2 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Check if auto-mergeable + id: check-update + run: | + UPDATE_TYPE="${{ steps.metadata.outputs.update-type }}" + if [[ "$UPDATE_TYPE" == "version-update:semver-patch" ]] || [[ "$UPDATE_TYPE" == "version-update:semver-minor" ]]; then + echo "auto_merge=true" >> $GITHUB_OUTPUT + else + echo "auto_merge=false" >> $GITHUB_OUTPUT + fi + + - name: Enable auto-merge for Dependabot PRs + if: steps.check-update.outputs.auto_merge == 'true' + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Approve PR + if: steps.check-update.outputs.auto_merge == 'true' + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Comment on major updates + if: steps.metadata.outputs.update-type == 'version-update:semver-major' + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: '⚠️ This is a **major version update**. Please review carefully before merging.' + }); diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000..6404fd0b --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,19 @@ +name: Auto Label PRs + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + configuration-path: .github/labeler.yml + sync-labels: true diff --git a/.github/workflows/size-check.yml b/.github/workflows/size-check.yml new file mode 100644 index 00000000..60a3327d --- /dev/null +++ b/.github/workflows/size-check.yml @@ -0,0 +1,87 @@ +name: Bundle Size Check + +on: + pull_request: + branches: [main, develop] + paths: + - 'packages/**/*.ts' + - 'packages/**/*.tsx' + - 'packages/**/package.json' + - 'pnpm-lock.yaml' + +permissions: + contents: read + pull-requests: write + +jobs: + size-check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build packages + run: pnpm build + + - name: Check bundle sizes + id: size-check + run: | + echo "## 📦 Bundle Size Report" > size-report.md + echo "" >> size-report.md + echo "| Package | Size | Gzipped |" >> size-report.md + echo "|---------|------|---------|" >> size-report.md + + for pkg in packages/*/dist; do + if [ -d "$pkg" ]; then + pkg_name=$(basename $(dirname $pkg)) + + # Calculate sizes for main bundle files + for file in "$pkg"/*.js; do + if [ -f "$file" ] && [ ! -f "${file}.map" ]; then + # Use portable method to get file size + size=$(wc -c < "$file") + size_kb=$(awk "BEGIN {printf \"%.2f\", $size/1024}") + + # Estimate gzipped size + gzip_size=$(gzip -c "$file" | wc -c) + gzip_kb=$(awk "BEGIN {printf \"%.2f\", $gzip_size/1024}") + + echo "| $pkg_name ($(basename $file)) | ${size_kb}KB | ${gzip_kb}KB |" >> size-report.md + fi + done + fi + done + + echo "" >> size-report.md + echo "### Size Limits" >> size-report.md + echo "- ✅ Core packages should be < 50KB gzipped" >> size-report.md + echo "- ✅ Component packages should be < 100KB gzipped" >> size-report.md + echo "- ⚠️ Plugin packages should be < 150KB gzipped" >> size-report.md + + - name: Comment PR + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const report = fs.readFileSync('size-report.md', 'utf8'); + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: report + }); diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..838d1ac5 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,72 @@ +name: Stale Issues & PRs + +on: + schedule: + # Run daily at 00:00 UTC + - cron: '0 0 * * *' + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@e00e804f6792d3fedb5bd3a27df2761c5f86c981 # v9.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + # Issues configuration + stale-issue-message: | + This issue has been automatically marked as stale because it has not had recent activity. + It will be closed in 7 days if no further activity occurs. + + If you believe this issue is still relevant, please: + - Comment on this issue to keep it open + - Add more details or context + - Update to the latest version and confirm the issue still exists + + Thank you for your contributions! + close-issue-message: | + This issue has been automatically closed due to inactivity. + + If you believe this issue should remain open, please: + - Reopen the issue with updated information + - Create a new issue with a detailed description and reproduction steps + + Thank you for your understanding! + stale-issue-label: 'stale' + exempt-issue-labels: 'pinned,security,critical,bug,enhancement' + days-before-issue-stale: 60 + days-before-issue-close: 7 + + # Pull requests configuration + stale-pr-message: | + This pull request has been automatically marked as stale because it has not had recent activity. + It will be closed in 14 days if no further activity occurs. + + If you're still working on this PR: + - Comment on this PR to keep it open + - Rebase on the latest main branch + - Address any review comments + + Thank you for your contributions! + close-pr-message: | + This pull request has been automatically closed due to inactivity. + + If you'd like to continue working on this: + - Reopen the PR and rebase on the latest main branch + - Create a new PR with updated changes + + Thank you for your understanding! + stale-pr-label: 'stale' + exempt-pr-labels: 'pinned,security,in-progress,blocked' + days-before-pr-stale: 45 + days-before-pr-close: 14 + + # General configuration + operations-per-run: 100 + remove-stale-when-updated: true + ascending: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19a11af3..7cff0a10 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -340,6 +340,39 @@ refactor: simplify expression evaluator - Respond to review comments promptly - Keep commits clean and meaningful +### Automated Workflows + +Our repository includes several automated GitHub workflows that will run when you create a PR: + +#### CI Pipeline +- **Linting**: Checks code style and quality +- **Type Checking**: Validates TypeScript types +- **Tests**: Runs unit and integration tests +- **Build**: Ensures all packages build successfully +- **Matrix Testing**: Tests on Node.js 18.x and 20.x + +#### Security Scans +- **CodeQL**: Scans for security vulnerabilities in code +- **Dependency Scanning**: Checks for known vulnerabilities in dependencies + +#### PR Automation +- **Auto-labeling**: Automatically labels PRs based on changed files +- **Bundle Size**: Reports bundle size changes in PR comments +- **PR Checks**: Validates PR requirements and posts status + +#### What to Expect +1. All checks must pass before merging +2. Failed checks will show detailed error messages +3. Some workflows (like auto-labeling) run automatically +4. Review the check results and fix any issues + +#### Tips for Passing Checks +- Run `pnpm lint` before committing +- Run `pnpm test` to catch test failures early +- Run `pnpm build` to ensure successful builds +- Keep dependencies up to date +- Follow TypeScript strict mode requirements + ## Documentation ### Writing Documentation diff --git a/README.md b/README.md index c9001c7c..f19e86f0 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ *From JSON to world-class UI in minutes* [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![CI](https://github.com/objectstack-ai/objectui/workflows/CI/badge.svg)](https://github.com/objectstack-ai/objectui/actions/workflows/ci.yml) +[![CodeQL](https://github.com/objectstack-ai/objectui/workflows/CodeQL%20Security%20Scan/badge.svg)](https://github.com/objectstack-ai/objectui/actions/workflows/codeql.yml) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/) [![React](https://img.shields.io/badge/React-18+-61dafb.svg)](https://reactjs.org/) [![Tailwind CSS](https://img.shields.io/badge/Tailwind-3.0+-38bdf8.svg)](https://tailwindcss.com/) diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 00000000..b61424ec --- /dev/null +++ b/cliff.toml @@ -0,0 +1,76 @@ +# git-cliff ~ configuration file +# https://git-cliff.org/docs/configuration + +[changelog] +# changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n +""" +# template for the changelog body +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %}\n +""" +# remove the leading and trailing whitespace from the template +trim = true +# changelog footer +footer = """ + +""" + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/objectstack-ai/objectui/issues/${2}))"}, +] +# regex for parsing and grouping commits +commit_parsers = [ + { message = "^feat", group = "Features"}, + { message = "^fix", group = "Bug Fixes"}, + { message = "^doc", group = "Documentation"}, + { message = "^perf", group = "Performance"}, + { message = "^refactor", group = "Refactor"}, + { message = "^style", group = "Styling"}, + { message = "^test", group = "Testing"}, + { message = "^chore\\(release\\): prepare for", skip = true}, + { message = "^chore\\(deps\\)", skip = true}, + { message = "^chore\\(pr\\)", skip = true}, + { message = "^chore\\(pull\\)", skip = true}, + { message = "^chore|ci", group = "Miscellaneous Tasks"}, + { body = ".*security", group = "Security"}, + { message = "^revert", group = "Revert"}, +] +# protect breaking changes from being skipped due to matching a skipping commit_parser +protect_breaking_commits = false +# filter out the commits that are not matched by commit parsers +filter_commits = false +# glob pattern for matching git tags +tag_pattern = "v[0-9]*" +# regex for skipping tags +skip_tags = "v0.1.0-beta.1" +# regex for ignoring tags +ignore_tags = "" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" +# limit the number of commits included in the changelog. +# limit_commits = 42